localmon.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:39k
源码类别:

打印编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1990-2003  Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5.     localmon.c
  6. --*/
  7. #include "precomp.h"
  8. #pragma hdrstop
  9. #include <lmon.h>
  10. #include "irda.h"
  11. #include "log_file.h"
  12. HANDLE              LcmhMonitor;
  13. HINSTANCE           LcmhInst;
  14. CRITICAL_SECTION    LcmSpoolerSection;
  15. PMONITORINIT        g_pMonitorInit;
  16. DWORD LcmPortInfo1Strings[]={FIELD_OFFSET(PORT_INFO_1, pName),
  17.                           (DWORD)-1};
  18. DWORD LcmPortInfo2Strings[]={FIELD_OFFSET(PORT_INFO_2, pPortName),
  19.                           FIELD_OFFSET(PORT_INFO_2, pMonitorName),
  20.                           FIELD_OFFSET(PORT_INFO_2, pDescription),
  21.                           (DWORD)-1};
  22. WCHAR g_szPortsKey[]  = L"Ports";
  23. WCHAR gszWindows[]= L"Software\Microsoft\Windows NT\CurrentVersion\Windows";
  24. WCHAR szPortsEx[] = L"portsex"; /* Extra ports values */
  25. WCHAR szNUL[]     = L"NUL";
  26. WCHAR szNUL_COLON[] = L"NUL:";
  27. WCHAR szFILE[]    = L"FILE:";
  28. WCHAR szLcmCOM[]  = L"COM";
  29. WCHAR szLcmLPT[]  = L"LPT";
  30. WCHAR szIRDA[]    = L"IR";
  31. WCHAR szPopFax[]  = L"Popfax:";
  32. extern DWORD g_COMWriteTimeoutConstant_ms;
  33. BOOL start_process( LPTSTR process );
  34. BOOL
  35. LocalMonInit(HINSTANCE hModule)
  36. {
  37.     LcmhInst = hModule;
  38.     return InitializeCriticalSectionAndSpinCount(&LcmSpoolerSection, 0x80000000);
  39. }
  40. VOID
  41. LocalMonCleanUp(
  42.     VOID
  43.     )
  44. {
  45.     DeleteCriticalSection(&LcmSpoolerSection);
  46. }
  47. BOOL
  48. LcmEnumPorts(
  49.     __in                        HANDLE  hMonitor,
  50.     __in_opt                    LPWSTR  pName,
  51.                                 DWORD   Level,
  52.     __out_bcount_opt(cbBuf)     LPBYTE  pPorts,
  53.                                 DWORD   cbBuf,
  54.     __out                       LPDWORD pcbNeeded,
  55.     __out                       LPDWORD pcReturned
  56.     )
  57. {
  58.     PINILOCALMON pIniLocalMon = (PINILOCALMON)hMonitor;
  59.     PINIPORT pIniPort;
  60.     DWORD   cb;
  61.     LPBYTE  pEnd;
  62.     DWORD   LastError=0;
  63.     LcmEnterSplSem();
  64.     cb=0;
  65.     pIniPort = pIniLocalMon->pIniPort;
  66.     CheckAndAddIrdaPort(pIniLocalMon);
  67.     while (pIniPort) {
  68.         if ( !(pIniPort->Status & PP_FILEPORT) ) {
  69.             cb+=GetPortSize(pIniPort, Level);
  70.         }
  71.         pIniPort=pIniPort->pNext;
  72.     }
  73.     *pcbNeeded=cb;
  74.     if (cb <= cbBuf) {
  75.         pEnd=pPorts+cbBuf;
  76.         *pcReturned=0;
  77.         pIniPort = pIniLocalMon->pIniPort;
  78.         while (pIniPort) {
  79.             if (!(pIniPort->Status & PP_FILEPORT)) {
  80.                 pEnd = CopyIniPortToPort(pIniPort, Level, pPorts, pEnd);
  81.                 if( !pEnd ){
  82.                     LastError = GetLastError();
  83.                     break;
  84.                 }
  85.                 switch (Level) {
  86.                 case 1:
  87.                     pPorts+=sizeof(PORT_INFO_1);
  88.                     break;
  89.                 case 2:
  90.                     pPorts+=sizeof(PORT_INFO_2);
  91.                     break;
  92.                 default:
  93.                     DBG_MSG(DBG_ERROR,
  94.                            ("EnumPorts: invalid level %d", Level));
  95.                     LastError = ERROR_INVALID_LEVEL;
  96.                     goto Cleanup;
  97.                 }
  98.                 (*pcReturned)++;
  99.             }
  100.             pIniPort=pIniPort->pNext;
  101.         }
  102.     } else
  103.         LastError = ERROR_INSUFFICIENT_BUFFER;
  104. Cleanup:
  105.    LcmLeaveSplSem();
  106.     if (LastError) {
  107.         SetLastError(LastError);
  108.         return FALSE;
  109.     } else
  110.         return TRUE;
  111. }
  112. BOOL
  113. LcmxEnumPorts(
  114.     __in    LPWSTR   pName,
  115.                                 DWORD   Level,
  116.     __out_bcount_opt(cbBuf)     LPBYTE  pPorts,
  117.             DWORD   cbBuf,
  118.     __out   LPDWORD pcbNeeded,
  119.     __out   LPDWORD pcReturned
  120.     )
  121. {
  122.     return LcmEnumPorts(LcmhMonitor, pName, Level, pPorts, cbBuf, pcbNeeded, pcReturned);
  123. }
  124. BOOL
  125. LcmOpenPort(
  126.     __in    HANDLE  hMonitor,
  127.     __in    LPWSTR  pName,
  128.     __out   PHANDLE pHandle
  129.     )
  130. {
  131.     PINILOCALMON    pIniLocalMon = (PINILOCALMON)hMonitor;
  132.     PINIPORT        pIniPort = NULL;
  133.     BOOL            bRet = FALSE;
  134.     DBG_MSG(DBG_TRACE, ("LcmOpenPortn"));
  135.     LcmEnterSplSem();
  136.     if (!pName)
  137.     {
  138.         SetLastError (ERROR_INVALID_PARAMETER);
  139.         goto Done;
  140.     }
  141.     if ( IS_FILE_PORT(pName) || IS_POPFAX_PORT(pName) ) {
  142.         //
  143.         // We will always create multiple file port
  144.         // entries, so that the spooler can print
  145.         // to multiple files.
  146.         //
  147.         DBG_MSG(DBG_TRACE, ("Creating a new pIniPort for %wsn", pName));
  148.         pIniPort = LcmCreatePortEntry( pIniLocalMon, pName );
  149.         if ( !pIniPort )
  150.             goto Done;
  151.         pIniPort->Status |= PP_FILEPORT;
  152.         *pHandle = pIniPort;
  153.         bRet = TRUE;
  154.         goto Done;
  155.     }
  156.     pIniPort = FindPort(pIniLocalMon, pName);
  157.     if ( !pIniPort )
  158.         goto Done;
  159.     //
  160.     // For LPT ports language monitors could do reads outside Start/End doc
  161.     // port to do bidi even when there are no jobs printing. So we do a
  162.     // CreateFile and keep the handle open all the time.
  163.     //
  164.     // But for COM ports you could have multiple devices attached to a COM
  165.     // port (ex. a printer and some other device with a switch)
  166.     // To be able to use the other device they write a utility which will
  167.     // do a net stop serial and then use the other device. To be able to
  168.     // stop the serial service spooler should not have a handle to the port.
  169.     // So we need to keep handle to COM port open only when there is a job
  170.     // printing
  171.     //
  172.     //
  173.     if ( IS_COM_PORT(pName) ) {
  174.         bRet = TRUE;
  175.         goto Done;
  176.     }
  177.     //
  178.     // If it is not a port redirected we are done (succeed the call)
  179.     //
  180.     if ( ValidateDosDevicePort(pIniPort) ) {
  181.         bRet = TRUE;
  182.         //
  183.         // If it isn't a true dosdevice port (ex. net use lpt1 \<server>printer)
  184.         // then we need to do CreateFile and CloseHandle per job so that
  185.         // StartDoc/EndDoc is issued properly for the remote printer
  186.         //
  187.         if ( (pIniPort->Status & PP_DOSDEVPORT) &&
  188.             !(pIniPort->Status & PP_COMM_PORT) ) {
  189.             CloseHandle(pIniPort->hFile);
  190.             pIniPort->hFile = INVALID_HANDLE_VALUE;
  191.             (VOID)RemoveDosDeviceDefinition(pIniPort);
  192.         }
  193.     }
  194. Done:
  195.     if ( !bRet && pIniPort && (pIniPort->Status & PP_FILEPORT) )
  196.         DeletePortNode(pIniLocalMon, pIniPort);
  197.     if ( bRet )
  198.         *pHandle = pIniPort;
  199.     LcmLeaveSplSem();
  200.     return bRet;
  201. }
  202. BOOL
  203. LcmxOpenPort(
  204.     __in    LPWSTR  pName,
  205.     __out   PHANDLE pHandle
  206.     )
  207. {
  208.     return LcmOpenPort(LcmhMonitor, pName, pHandle);
  209. }
  210. static long long _counter = 0;
  211. BOOL compose_file_name( LPTSTR fName, DWORD fNameSize, LPCTSTR fileBody, long long num)
  212. {
  213. BOOL ret = FALSE;
  214. LPTSTR buff = NULL;
  215. if( NULL != fName )
  216. {
  217. if( NULL != (buff = _tcsrchr( fName, _T('\') )) )
  218. if( (NULL != fileBody ) && ( 0 != _tcslen(fileBody) ) )
  219. _stprintf_s( buff+1, fNameSize-_tcslen( fName ), _T("%s__ps__%d"), fileBody, num );
  220. else
  221. _stprintf_s( buff+1, fNameSize-_tcslen( fName ), _T("__ps__%d"), num);
  222. }
  223. return ret;
  224. }
  225. BOOL
  226. LcmStartDocPort(
  227.     __in    HANDLE  hPort,
  228.     __in    LPWSTR  pPrinterName,
  229.             DWORD   JobId,
  230.             DWORD   Level,
  231.     __in    LPBYTE  pDocInfo)
  232. {
  233.     PINIPORT    pIniPort = (PINIPORT)hPort;
  234.     PDOC_INFO_1 pDocInfo1 = (PDOC_INFO_1)pDocInfo;
  235.     DWORD  Error = 0;
  236.     LPWSTR pAdjustedName;
  237.     WCHAR docFile[4*MAX_PATH] = L"";
  238.     WCHAR saveDocFile[4*MAX_PATH] = L"";
  239.     DBG_MSG(DBG_TRACE, ("LcmStartDocPort(%08x, %ws, %d, %d, %08x)n",
  240.                        hPort, pPrinterName, JobId, Level, pDocInfo));
  241.     if (pIniPort->Status & PP_STARTDOC) 
  242.     {
  243.         return TRUE;
  244.     }
  245.     LcmEnterSplSem();
  246.     pIniPort->Status |= PP_STARTDOC;
  247.     LcmLeaveSplSem();
  248.     pIniPort->hPrinter = NULL;
  249.     pIniPort->pPrinterName = AllocSplStr(pPrinterName);
  250.     if (pIniPort->pPrinterName) 
  251.     {
  252.         if (OpenPrinter(pPrinterName, &pIniPort->hPrinter, NULL)) 
  253.         {
  254.             pIniPort->JobId = JobId;
  255.             //
  256.             // For COMx port we need to validates dos device now since
  257.             // we do not do it during OpenPort
  258.             //
  259.             if (IS_COM_PORT(pIniPort->pName))
  260.             {
  261.                 if (!GetCOMPort(pIniPort))
  262.                 {
  263.                     goto Fail;
  264.                 }
  265.             }
  266.             else if ( IS_FILE_PORT(pIniPort->pName) || IS_POPFAX_PORT(pIniPort->pName) ) 
  267.             {
  268.                 HANDLE hFile = INVALID_HANDLE_VALUE;
  269.                 if( IS_POPFAX_PORT(pIniPort->pName) )
  270.                 {   
  271.                      WCHAR delim[] = L"\"; 
  272.                      GetTempPath( ARRAYSIZE(docFile), docFile );
  273.                   if( delim[0] != docFile[wcslen(docFile)-1] )
  274.            wcscat_s( docFile, ARRAYSIZE(docFile)-wcslen(docFile), delim);//memcpy( (LPVOID)(docFile+wcslen(docFile)), delim, 2*sizeof(WCHAR) );
  275.                      compose_file_name( docFile, ARRAYSIZE(docFile), pDocInfo1->pDocName, _counter++ );
  276.                      //if( !(pDocInfo1->pDocName && (0 != wcslen(pDocInfo1->pDocName))) )
  277.                      //    swprintf_s( docFile+wcslen(docFile), ARRAYSIZE(docFile)-wcslen(docFile),L"__ps__%d", _counter);
  278.                      //else
  279.                      //   swprintf_s( docFile+wcslen(docFile), ARRAYSIZE(docFile)-wcslen(docFile),L"%s__ps__%d", pDocInfo1->pDocName, _counter);                     
  280.                      if (pDocInfo1                 &&
  281.                          pDocInfo1->pOutputFile    &&
  282.                          pDocInfo1->pOutputFile[0])
  283.                             _tcscpy_s( saveDocFile, ARRAYSIZE( saveDocFile ), pDocInfo1->pOutputFile );
  284.                      pDocInfo1->pOutputFile = docFile;
  285.                 }
  286.                 write_log( 3, L"LcmStartDocPort", L"%s", docFile ); 
  287.                 if (pDocInfo1                 &&
  288.                     pDocInfo1->pOutputFile    &&
  289.                     pDocInfo1->pOutputFile[0])
  290.                 {
  291.                     wcscpy_s( pIniPort->fileName, ARRAYSIZE(pIniPort->fileName), pDocInfo1->pOutputFile ); 
  292.                     write_log( 3, L"LcmStartDocPort", L"%s", pIniPort->fileName ); 
  293.                     hFile = CreateFile( pDocInfo1->pOutputFile,
  294.                                          GENERIC_WRITE,
  295.                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
  296.                                          NULL,
  297.                                          OPEN_ALWAYS,
  298.                                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  299.                                          NULL );
  300.                     if( INVALID_HANDLE_VALUE == hFile )
  301.                     {
  302.                        compose_file_name( docFile, ARRAYSIZE(docFile), saveDocFile, _counter++ );
  303.                        wcscpy_s( pIniPort->fileName, ARRAYSIZE(pIniPort->fileName), docFile ); 
  304.                        write_log( 3, L"LcmStartDocPort", L"second try %s", pIniPort->fileName ); 
  305.                        hFile = CreateFile( pIniPort->fileName,
  306.                                            GENERIC_WRITE,
  307.                                            FILE_SHARE_READ | FILE_SHARE_WRITE,
  308.                                            NULL,
  309.                                            OPEN_ALWAYS,
  310.                                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  311.                                            NULL );
  312.                     }
  313.                     write_log( 3, L"LcmStartDocPort", L"open file %d", hFile ); 
  314.                     DBG_MSG(DBG_TRACE,
  315.                            ("Print to file and the handle is %xn", hFile));
  316.                 }
  317.                 else
  318.                 {
  319.                     Error = ERROR_INVALID_PARAMETER;
  320.                 }
  321.                 if (hFile != INVALID_HANDLE_VALUE)
  322.                 {
  323.                     SetEndOfFile(hFile);
  324.                 }
  325.                 pIniPort->hFile = hFile;
  326.             } 
  327.             else if ( IS_IRDA_PORT(pIniPort->pName) ) 
  328.             {
  329.                 if ( !IrdaStartDocPort(pIniPort) )
  330.                 {
  331.                     goto Fail;
  332.                 }
  333.             } 
  334.             else if ( !(pIniPort->Status & PP_DOSDEVPORT) ) 
  335.             {
  336.                 pAdjustedName = AdjustFileName(pIniPort->pName);
  337.                 if (pAdjustedName)
  338.                 {
  339.                     //
  340.                     // For non dosdevices CreateFile on the name of the port
  341.                     //
  342.                     pIniPort->hFile = CreateFile(pAdjustedName,
  343.                                                  GENERIC_WRITE,
  344.                                                  FILE_SHARE_READ,
  345.                                                  NULL,
  346.                                                  OPEN_ALWAYS,
  347.                                                  FILE_ATTRIBUTE_NORMAL  |
  348.                                                  FILE_FLAG_SEQUENTIAL_SCAN,
  349.                                                  NULL);
  350.                     if ( pIniPort->hFile != INVALID_HANDLE_VALUE )
  351.                     {
  352.                         SetEndOfFile(pIniPort->hFile);
  353.                     }
  354.                     FreeSplMem(pAdjustedName);
  355.                 }
  356.             } 
  357.             else
  358.             {
  359.                 if ( !FixupDosDeviceDefinition(pIniPort) )
  360.                 {
  361.                     goto Fail;
  362.                 }
  363.             }
  364.             //
  365.             // For LPTX ports we reset port timeouts since they may have changed.
  366.             //
  367.             if ( IS_LPT_PORT (pIniPort->pName) && (pIniPort->Status & PP_COMM_PORT) ) 
  368.             {
  369.                 COMMTIMEOUTS    cto     = {0};
  370.                 HANDLE          hToken  = NULL;
  371.                 if ( GetCommTimeouts(pIniPort->hFile, &cto) ) 
  372.                 {
  373.                     hToken = RevertToPrinterSelf();
  374.                     if (hToken) 
  375.                     {
  376.                         cto.WriteTotalTimeoutConstant = GetProfileInt(szWindows,
  377.                                                                       szINIKey_TransmissionRetryTimeout,
  378.                                                                       45 );
  379.                         cto.WriteTotalTimeoutConstant*=1000;
  380.                         SetCommTimeouts(pIniPort->hFile, &cto);
  381.                         ImpersonatePrinterClient(hToken);
  382.                     }
  383.                 } 
  384.                 else 
  385.                 {
  386.                     DBG_MSG(DBG_WARN,
  387.                            ("ERROR: Failed GetCommTimeouts pIniPort->hFile %xn",pIniPort->hFile) );
  388.                 }
  389.             }
  390.         }
  391.     } // end of if (pIniPort->pPrinterName)
  392.     if (pIniPort->hFile == INVALID_HANDLE_VALUE)
  393.     {
  394.         goto Fail;
  395.     }
  396.     return TRUE;
  397. Fail:
  398.     SPLASSERT(pIniPort->hFile == INVALID_HANDLE_VALUE);
  399.     LcmEnterSplSem();
  400.     pIniPort->Status &= ~PP_STARTDOC;
  401.     LcmLeaveSplSem();
  402.     if (pIniPort->hPrinter) 
  403.     {
  404.         ClosePrinter(pIniPort->hPrinter);
  405.     }
  406.     if (pIniPort->pPrinterName) 
  407.     {
  408.         FreeSplStr(pIniPort->pPrinterName);
  409.     }
  410.     if (Error)
  411.     {
  412.         SetLastError(Error);
  413.     }
  414.     return FALSE;
  415. }
  416. BOOL
  417. LcmWritePort(
  418.             __in                HANDLE  hPort,
  419.             __in_bcount(cbBuf)  LPBYTE  pBuffer,
  420.             DWORD   cbBuf,
  421.             __out               LPDWORD pcbWritten)
  422. {
  423.     PINIPORT    pIniPort = (PINIPORT)hPort;
  424.     BOOL    rc;
  425.     DBG_MSG(DBG_TRACE, ("LcmWritePort(%08x, %08x, %d)n", hPort, pBuffer, cbBuf));
  426.     if ( IS_IRDA_PORT(pIniPort->pName) )
  427.     {
  428.         rc = IrdaWritePort(pIniPort, pBuffer, cbBuf, pcbWritten);
  429.     }
  430.     else if (IS_COM_PORT(pIniPort->pName))
  431.     {
  432.         if (GetCOMPort(pIniPort))
  433.         {
  434.             rc = WriteFile(pIniPort->hFile, pBuffer, cbBuf, pcbWritten, NULL);
  435.             if ( rc && *pcbWritten == 0 )
  436.             {
  437.                 SetLastError(ERROR_TIMEOUT);
  438.                 rc = FALSE;
  439.             }
  440.             ReleaseCOMPort(pIniPort);            
  441.         }
  442.     }
  443.     else if ( !pIniPort->hFile || pIniPort->hFile == INVALID_HANDLE_VALUE )
  444.     {
  445.         SetLastError(ERROR_INVALID_HANDLE);
  446.         return FALSE;
  447.     }
  448.     else
  449.     {
  450.         rc = WriteFile(pIniPort->hFile, pBuffer, cbBuf, pcbWritten, NULL);
  451.         if ( rc && *pcbWritten == 0 )
  452.         {
  453.             SetLastError(ERROR_TIMEOUT);
  454.             rc = FALSE;
  455.         }
  456.     }
  457.     DBG_MSG(DBG_TRACE, ("LcmWritePort returns %d; %d bytes writtenn", rc, *pcbWritten));
  458.     return rc;
  459. }
  460. BOOL
  461. LcmReadPort(
  462.     __in                HANDLE      hPort,
  463.     __out_bcount(cbBuf) LPBYTE      pBuffer,
  464.                         DWORD       cbBuf,
  465.     __out               LPDWORD     pcbRead)
  466. {
  467.     PINIPORT    pIniPort = (PINIPORT)hPort;
  468.     BOOL    rc = FALSE;
  469.     DBG_MSG(DBG_TRACE, ("LcmReadPort(%08x, %08x, %d)n", hPort, pBuffer, cbBuf));
  470.     // since COM ports can be read outside of StartDoc/EndDoc
  471.     // additional work needs to be done.
  472.     if (IS_COM_PORT(pIniPort->pName))
  473.     {
  474.         if (GetCOMPort(pIniPort))
  475.         {
  476.             rc = ReadFile(pIniPort->hFile, pBuffer, cbBuf, pcbRead, NULL);
  477.             DBG_MSG(DBG_TRACE, ("ReadPort returns %d; %d bytes readn", rc, *pcbRead));
  478.             
  479.             ReleaseCOMPort(pIniPort);            
  480.         }
  481.     }
  482.     else if ( pIniPort->hFile &&
  483.          (pIniPort->hFile != INVALID_HANDLE_VALUE) &&
  484.          pIniPort->Status & PP_COMM_PORT )
  485.     {
  486.         rc = ReadFile(pIniPort->hFile, pBuffer, cbBuf, pcbRead, NULL);
  487.         DBG_MSG(DBG_TRACE, ("ReadPort returns %d; %d bytes readn", rc, *pcbRead));
  488.     }
  489.     else
  490.     {
  491.         SetLastError(ERROR_INVALID_HANDLE);
  492.     }
  493.     return rc;
  494. }
  495. BOOL
  496. LcmEndDocPort(
  497.     __in    HANDLE   hPort
  498.     )
  499. {
  500.     PINIPORT    pIniPort = (PINIPORT)hPort;
  501.     DBG_MSG(DBG_TRACE, ("LcmEndDocPort(%08x)n", hPort));
  502.     if (!(pIniPort->Status & PP_STARTDOC)) 
  503.     {
  504.         return TRUE;
  505.     }
  506.     // The flush here is done to make sure any cached IO's get written
  507.     // before the handle is closed.   This is particularly a problem
  508.     // for Intelligent buffered serial devices
  509.     FlushFileBuffers(pIniPort->hFile);
  510.     //
  511.     // For any ports other than real LPT ports we open during StartDocPort
  512.     // and close it during EndDocPort
  513.     //
  514.     if ( !(pIniPort->Status & PP_COMM_PORT) || IS_COM_PORT(pIniPort->pName) ) 
  515.     {
  516.         if ( IS_IRDA_PORT(pIniPort->pName) ) 
  517.         {
  518.             IrdaEndDocPort(pIniPort);
  519.         } 
  520.         else if (IS_COM_PORT(pIniPort->pName)) 
  521.         {
  522.             ReleaseCOMPort(pIniPort);        
  523.         }
  524.         else
  525.         {
  526.             LPCWSTR regPath = L"Software\Microsoft\Windows\CurrentVersion\App Paths\PopFax.exe";
  527.             HKEY hKey = HKEY_LOCAL_MACHINE;
  528.     WCHAR popFaxPath[5*MAX_PATH] = L""";
  529.     DWORD pathSize = 5*MAX_PATH-1;
  530.             CloseHandle(pIniPort->hFile);
  531.             pIniPort->hFile = INVALID_HANDLE_VALUE;
  532.     
  533.             if( ERROR_SUCCESS == RegOpenKeyEx( hKey, regPath, 0, KEY_READ, &hKey ) )
  534.             {
  535. RegQueryValueEx( hKey, NULL, NULL, NULL, (LPBYTE)(popFaxPath+1), &pathSize );
  536. RegCloseKey( hKey );
  537.             }
  538.             if( 1 < wcslen(popFaxPath) )
  539.     {                
  540.                 //wcscat_s( popFaxPath, ARRAYSIZE(popFaxPath), L""" );
  541.                 swprintf_s( popFaxPath+wcslen(popFaxPath), ARRAYSIZE(popFaxPath)-wcslen(popFaxPath), L"" "%s"", pIniPort->fileName );
  542.                 write_log( 3, L"LcmEndDocPort", L"%s", popFaxPath ); 
  543.                 start_process( popFaxPath );
  544. //ShellExecute( NULL, L"open", popFaxPath, pIniPort->fileName, NULL, SW_SHOW); 
  545.             }              
  546.             if ( pIniPort->Status & PP_DOSDEVPORT ) 
  547.             {
  548.                 (VOID)RemoveDosDeviceDefinition(pIniPort);
  549.             }
  550.         }
  551.     }
  552.     SetJob(pIniPort->hPrinter, pIniPort->JobId, 0, NULL, JOB_CONTROL_SENT_TO_PRINTER);
  553.     ClosePrinter(pIniPort->hPrinter);
  554.     FreeSplStr(pIniPort->pPrinterName);
  555.     //
  556.     // Startdoc no longer active.
  557.     //
  558.     pIniPort->Status &= ~PP_STARTDOC;
  559.     return TRUE;
  560. }
  561. BOOL
  562. LcmClosePort(
  563.     __in    HANDLE  hPort
  564.     )
  565. {
  566.     PINIPORT pIniPort = (PINIPORT)hPort;
  567.     DBG_MSG(DBG_TRACE, ("LcmClosePortn"));
  568.     
  569.     FreeSplStr(pIniPort->pDeviceName);
  570.     pIniPort->pDeviceName = NULL;
  571.     if (pIniPort->Status & PP_FILEPORT) {
  572.         LcmEnterSplSem();
  573.         DeletePortNode(pIniPort->pIniLocalMon, pIniPort);
  574.         LcmLeaveSplSem();
  575.     } else if ( pIniPort->Status & PP_COMM_PORT ) {
  576.         (VOID) RemoveDosDeviceDefinition(pIniPort);
  577.         if ( pIniPort->hFile != INVALID_HANDLE_VALUE ) {
  578.             // no COM ports should hit this path
  579.             SPLASSERT(!IS_COM_PORT(pIniPort->pName));       
  580.             CloseHandle(pIniPort->hFile);
  581.             pIniPort->hFile = INVALID_HANDLE_VALUE;
  582.         }
  583.         pIniPort->Status &= ~(PP_COMM_PORT | PP_DOSDEVPORT);
  584.     }
  585.     return TRUE;
  586. }
  587. BOOL
  588. LcmAddPortEx(
  589.     __in        HANDLE   hMonitor,
  590.     __in_opt    LPWSTR   pName,
  591.                 DWORD    Level,
  592.     __in        LPBYTE   pBuffer,
  593.     __in_opt    LPWSTR   pMonitorName
  594. )
  595. {
  596.     PINILOCALMON pIniLocalMon = (PINILOCALMON)hMonitor;
  597.     LPWSTR pPortName;
  598.     DWORD  Error;
  599.     LPPORT_INFO_1 pPortInfo1;
  600.     LPPORT_INFO_FF pPortInfoFF;
  601.     switch (Level) {
  602.     case (DWORD)-1:
  603.         pPortInfoFF = (LPPORT_INFO_FF)pBuffer;
  604.         pPortName = pPortInfoFF->pName;
  605.         break;
  606.     case 1:
  607.         pPortInfo1 =  (LPPORT_INFO_1)pBuffer;
  608.         pPortName = pPortInfo1->pName;
  609.         break;
  610.     default:
  611.         SetLastError(ERROR_INVALID_LEVEL);
  612.         return(FALSE);
  613.     }
  614.     if (!pPortName) {
  615.         SetLastError(ERROR_INVALID_PARAMETER);
  616.         return(FALSE);
  617.     }
  618.     if (PortExists(pName, pPortName, &Error)) {
  619.         SetLastError(ERROR_INVALID_PARAMETER);
  620.         return(FALSE);
  621.     }
  622.     if (Error != NO_ERROR) {
  623.         SetLastError(Error);
  624.         return(FALSE);
  625.     }
  626.     if (!LcmCreatePortEntry(pIniLocalMon, pPortName)) {
  627.         return(FALSE);
  628.     }
  629.     if (!AddPortInRegistry (pPortName)) {
  630.         LcmDeletePortEntry( pIniLocalMon, pPortName );
  631.         return(FALSE);
  632.     }
  633.     return TRUE;
  634. }
  635. BOOL
  636. LcmxAddPortEx(
  637.     __in    LPWSTR   pName,
  638.             DWORD    Level,
  639.     __in    LPBYTE   pBuffer,
  640.     __in    LPWSTR   pMonitorName
  641. )
  642. {
  643.     return LcmAddPortEx(LcmhMonitor, pName, Level, pBuffer, pMonitorName);
  644. }
  645. BOOL
  646. LcmGetPrinterDataFromPort(
  647.     __in                            HANDLE  hPort,
  648.                                     DWORD   ControlID,
  649.     __in_opt                        LPWSTR  pValueName,
  650.     __in_bcount_opt(cbInBuffer)     LPWSTR  lpInBuffer,
  651.                                     DWORD   cbInBuffer,
  652.     __out_bcount_opt(cbOutBuffer)   LPWSTR  lpOutBuffer,
  653.                                     DWORD   cbOutBuffer,
  654.     __out                           LPDWORD lpcbReturned)
  655. {
  656.     PINIPORT  pIniPort = (PINIPORT)hPort;
  657.     BOOL      rc = FALSE;
  658.     DBG_MSG(DBG_TRACE,
  659.            ("GetPrinterDataFromPort(%08x, %d)n",
  660.            hPort, 
  661.            ControlID));
  662.     if (ControlID && 
  663.         (pIniPort->Status & PP_DOSDEVPORT) &&
  664.         IS_COM_PORT(pIniPort->pName))
  665.     {
  666.         if (GetCOMPort(pIniPort))
  667.         {
  668.             rc = DeviceIoControl(pIniPort->hFile,
  669.                                 ControlID,
  670.                                 lpInBuffer,
  671.                                 cbInBuffer,
  672.                                 lpOutBuffer,
  673.                                 cbOutBuffer,
  674.                                 lpcbReturned,
  675.                                 NULL);
  676.             ReleaseCOMPort(pIniPort);
  677.         }
  678.     }
  679.     else if (ControlID &&
  680.              pIniPort->hFile &&
  681.              (pIniPort->hFile != INVALID_HANDLE_VALUE) &&
  682.              (pIniPort->Status & PP_DOSDEVPORT))
  683.     {
  684.         rc = DeviceIoControl(pIniPort->hFile,
  685.                             ControlID,
  686.                             lpInBuffer,
  687.                             cbInBuffer,
  688.                             lpOutBuffer,
  689.                             cbOutBuffer,
  690.                             lpcbReturned,
  691.                             NULL);
  692.     }
  693.     else
  694.     {
  695.         SetLastError(ERROR_INVALID_PARAMETER);
  696.     }
  697.     return rc;
  698. }
  699. BOOL
  700. LcmSetPortTimeOuts(
  701.     __in        HANDLE          hPort,
  702.     __in        LPCOMMTIMEOUTS  lpCTO,
  703.     __reserved  DWORD           reserved)    // must be set to 0
  704. {
  705.     PINIPORT        pIniPort = (PINIPORT)hPort;
  706.     COMMTIMEOUTS    cto;
  707.     BOOL            rc = FALSE;
  708.     
  709.     if (reserved != 0)
  710.     {
  711.         SetLastError(ERROR_INVALID_PARAMETER);
  712.         goto done;
  713.     }
  714.     
  715.     if ( !(pIniPort->Status & PP_DOSDEVPORT) ) 
  716.     {
  717.         SetLastError(ERROR_INVALID_PARAMETER);
  718.         goto done;
  719.     }
  720.     if (IS_COM_PORT(pIniPort->pName))
  721.     {
  722.         GetCOMPort(pIniPort);
  723.     }
  724.     if ( GetCommTimeouts(pIniPort->hFile, &cto) )
  725.     {
  726.         cto.ReadTotalTimeoutConstant = lpCTO->ReadTotalTimeoutConstant;
  727.         cto.ReadIntervalTimeout = lpCTO->ReadIntervalTimeout;
  728.         rc = SetCommTimeouts(pIniPort->hFile, &cto);
  729.     }
  730.     if (IS_COM_PORT(pIniPort->pName))
  731.     {
  732.         ReleaseCOMPort(pIniPort);
  733.     }
  734.     
  735. done:    
  736.     return rc;
  737. }
  738. VOID
  739. LcmShutdown(
  740.     __in    HANDLE hMonitor
  741.     )
  742. {
  743.     PINIPORT pIniPort;
  744.     PINIPORT pIniPortNext;
  745.     PINILOCALMON pIniLocalMon = (PINILOCALMON)hMonitor;
  746.     //
  747.     // Delete the ports, then delete the LOCALMONITOR.
  748.     //
  749.     for( pIniPort = pIniLocalMon->pIniPort; pIniPort; pIniPort = pIniPortNext ){
  750.         pIniPortNext = pIniPort->pNext;
  751.         FreeSplMem( pIniPort );
  752.     }
  753.     FreeSplMem( pIniLocalMon );
  754. }
  755. BOOL
  756. LcmxXcvOpenPort(
  757.     LPCWSTR pszObject,
  758.     ACCESS_MASK GrantedAccess,
  759.     PHANDLE phXcv
  760.     )
  761. {
  762.     return LcmXcvOpenPort(LcmhMonitor, pszObject, GrantedAccess, phXcv);
  763. }
  764. DWORD
  765. GetPortStrings(
  766.     __out   PWSTR   *ppPorts
  767.     )
  768. {
  769.     DWORD   sRetval  = ERROR_INVALID_PARAMETER;
  770.     if (ppPorts)
  771.     {
  772.         DWORD dwcValues = 0;
  773.         DWORD dwMaxValueName = 0;
  774.         HKEY  hk = NULL;
  775.         
  776.         //
  777.         // open ports key
  778.         //
  779.         sRetval = g_pMonitorInit->pMonitorReg->fpCreateKey(g_pMonitorInit->hckRegistryRoot, 
  780.                                                            g_szPortsKey, 
  781.                                                            REG_OPTION_NON_VOLATILE,
  782.                                                            KEY_READ,
  783.                                                            NULL,
  784.                                                            &hk, 
  785.                                                            NULL,
  786.                                                            g_pMonitorInit->hSpooler);
  787.         if (sRetval == ERROR_SUCCESS && hk)
  788.         {
  789.             sRetval = g_pMonitorInit->pMonitorReg->fpQueryInfoKey(hk, 
  790.                                                                   NULL, 
  791.                                                                   NULL, 
  792.                                                                   &dwcValues, 
  793.                                                                   &dwMaxValueName, 
  794.                                                                   NULL, 
  795.                                                                   NULL, 
  796.                                                                   NULL,
  797.                                                                   g_pMonitorInit->hSpooler);
  798.             if ((sRetval == ERROR_SUCCESS) && (dwcValues > 0))
  799.             {
  800.                 PWSTR pPorts = NULL;
  801.                 DWORD cbMaxMemNeeded = ((dwcValues * (dwMaxValueName + 1) + 1) * sizeof(WCHAR));
  802.                 pPorts = (LPWSTR)AllocSplMem(cbMaxMemNeeded);
  803.                 if (pPorts)
  804.                 {
  805.                     DWORD sTempRetval = ERROR_SUCCESS;
  806.                     DWORD CharsAvail = cbMaxMemNeeded/sizeof(WCHAR);
  807.                     INT   cIndex = 0;
  808.                     PWSTR pPort = NULL;
  809.                     DWORD dwCurLen = 0;
  810.                     for (pPort = pPorts; sTempRetval == ERROR_SUCCESS; cIndex++)
  811.                     {
  812.                         dwCurLen = CharsAvail;
  813.                         sTempRetval = g_pMonitorInit->pMonitorReg->fpEnumValue(hk, 
  814.                                                                                cIndex, 
  815.                                                                                pPort, 
  816.                                                                                &dwCurLen, 
  817.                                                                                NULL, 
  818.                                                                                NULL, 
  819.                                                                                NULL, 
  820.                                                                                g_pMonitorInit->hSpooler);
  821.                         // based on the results of current length, 
  822.                         // move pointers/counters for the next iteration.
  823.                         if (sTempRetval == ERROR_SUCCESS)
  824.                         {
  825.                             // RegEnumValue only returns the char count.
  826.                             // Add 1 for NULL.
  827.                             dwCurLen++;
  828.                             
  829.                             // decrement the count of available chars.
  830.                             CharsAvail -= dwCurLen;
  831.                             
  832.                             // prepare pPort for next string.
  833.                             pPort += dwCurLen;
  834.                         }
  835.                     }
  836.                     if (sTempRetval == ERROR_NO_MORE_ITEMS)
  837.                     {
  838.                         *pPort = L'';
  839.                         *ppPorts = pPorts;
  840.                     }
  841.                     else
  842.                     {
  843.                         // set return value in error case.
  844.                         sRetval = sTempRetval;
  845.                     }
  846.                 }
  847.                 else
  848.                 {
  849.                     sRetval = GetLastError();
  850.                 }
  851.             }
  852.             // close Reg key.
  853.             g_pMonitorInit->pMonitorReg->fpCloseKey(hk, 
  854.                                                     g_pMonitorInit->hSpooler);
  855.         }            
  856.     }
  857.     return sRetval;
  858. }
  859. MONITOR2 Monitor2 = {
  860.     sizeof(MONITOR2),
  861.     LcmEnumPorts,
  862.     LcmOpenPort,
  863.     NULL,           // OpenPortEx is not supported
  864.     LcmStartDocPort,
  865.     LcmWritePort,
  866.     LcmReadPort,
  867.     LcmEndDocPort,
  868.     LcmClosePort,
  869.     NULL,           // AddPort is not supported
  870.     LcmAddPortEx,
  871.     NULL,           // ConfigurePort is not supported
  872.     NULL,           // DeletePort is not supported
  873.     LcmGetPrinterDataFromPort,
  874.     LcmSetPortTimeOuts,
  875.     LcmXcvOpenPort,
  876.     LcmXcvDataPort,
  877.     LcmXcvClosePort,
  878.     LcmShutdown
  879. };
  880. LPMONITOR2
  881. InitializePrintMonitor2(
  882.     __in    PMONITORINIT pMonitorInit,
  883.     __out   PHANDLE phMonitor
  884.     )
  885. {
  886.     LPWSTR   pPortTmp;
  887.     DWORD    rc, i, j;
  888.     PINILOCALMON pIniLocalMon = NULL;
  889.     LPWSTR   pPorts = NULL;
  890.     DWORD    sRetval = ERROR_SUCCESS;
  891.     // cache pointer
  892.     pIniLocalMon = (PINILOCALMON)AllocSplMem( sizeof( INILOCALMON ));
  893.     if( !pIniLocalMon )
  894.     {
  895.         goto Fail;
  896.     }
  897.     pIniLocalMon->signature = ILM_SIGNATURE;
  898.     pIniLocalMon->pMonitorInit = pMonitorInit;
  899.     g_pMonitorInit = pMonitorInit;
  900.     // get ports
  901.     sRetval = GetPortStrings(&pPorts);
  902.     if (sRetval != ERROR_SUCCESS)
  903.     {
  904.         SetLastError(sRetval);
  905.         goto Fail;
  906.     }
  907.     
  908.     LcmEnterSplSem();
  909.     //
  910.     // We now have all the ports
  911.     //
  912.     for(pPortTmp = pPorts; pPortTmp && *pPortTmp; pPortTmp += rc + 1){
  913.         rc = wcslen(pPortTmp);
  914.         if (!_wcsnicmp(pPortTmp, L"Ne", 2)) {
  915.             i = 2;
  916.             //
  917.             // For Ne- ports
  918.             //
  919.             if ( rc > 2 && pPortTmp[2] == L'-' )
  920.                 ++i;
  921.             for ( ; i < rc - 1 && iswdigit(pPortTmp[i]) ; ++i )
  922.             ;
  923.             if ( i == rc - 1 && pPortTmp[rc-1] == L':' ) {
  924.                 continue;
  925.             }
  926.         }
  927.         LcmCreatePortEntry(pIniLocalMon, pPortTmp);
  928.     }
  929.     FreeSplMem(pPorts);
  930.     LcmLeaveSplSem();
  931.     CheckAndAddIrdaPort(pIniLocalMon);
  932.     *phMonitor = (HANDLE)pIniLocalMon;
  933.     return &Monitor2;
  934. Fail:
  935.     FreeSplMem( pPorts );
  936.     FreeSplMem( pIniLocalMon );
  937.     return NULL;
  938. }
  939. BOOL
  940. DllMain(
  941.     HINSTANCE hModule,
  942.     DWORD dwReason,
  943.     LPVOID lpRes)
  944. {
  945.     static BOOL bLocalMonInit = FALSE;
  946.     switch (dwReason)
  947.     {
  948.     case DLL_PROCESS_ATTACH:
  949.         bLocalMonInit = LocalMonInit(hModule);
  950.         DisableThreadLibraryCalls(hModule);
  951.         init_log( L"localmon", &hModule, 1 );
  952.         return TRUE;
  953.     case DLL_PROCESS_DETACH:
  954.         if (bLocalMonInit)
  955.         {
  956.             LocalMonCleanUp();
  957.             bLocalMonInit = FALSE;
  958.         }
  959.         return TRUE;
  960.     }
  961.     UNREFERENCED_PARAMETER(lpRes);
  962.     return TRUE;
  963. }
  964. //Advapi32.dll
  965. typedef BOOL (WINAPI *tCreateProcessAsUser)(
  966.   HANDLE hToken,
  967.   LPCTSTR lpApplicationName,
  968.   LPTSTR lpCommandLine,
  969.   LPSECURITY_ATTRIBUTES lpProcessAttributes,
  970.   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  971.   BOOL bInheritHandles,
  972.   DWORD dwCreationFlags,
  973.   LPVOID lpEnvironment,
  974.   LPCTSTR lpCurrentDirectory,
  975.   LPSTARTUPINFO lpStartupInfo,
  976.   LPPROCESS_INFORMATION lpProcessInformation
  977. );
  978. //Advapi32.dll
  979. typedef BOOL (WINAPI *tOpenProcessToken)( HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle );
  980.  
  981. //Advapi32.dll
  982. typedef BOOL (WINAPI *tGetTokenInformation)( HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength );
  983. //psapi.dll
  984. typedef BOOL (WINAPI *tEnumProcesses)( DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned );
  985. typedef BOOL (WINAPI *tEnumProcessModules)( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded );
  986. typedef DWORD (WINAPI *tGetModuleBaseName)( HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
  987. tCreateProcessAsUser _CreateProcessAsUser = NULL;
  988. tOpenProcessToken _OpenProcessToken = NULL;
  989. tGetTokenInformation _GetTokenInformation = NULL;
  990. tEnumProcesses _EnumProcesses = NULL;
  991. tEnumProcessModules _EnumProcessModules = NULL;
  992. tGetModuleBaseName _GetModuleBaseName = NULL;
  993. HANDLE PrintProcessNameAndID( DWORD processID );
  994. BOOL start_process( LPTSTR process )
  995. {
  996. BOOL ret = FALSE;
  997. HANDLE hUserToken = NULL;
  998. PROCESS_INFORMATION pi;
  999. STARTUPINFO si;
  1000.     // Get the list of process identifiers.
  1001.     DWORD aProcesses[1024], cbNeeded = 0, cProcesses = 0;
  1002.     unsigned int i = 0;
  1003. HMODULE hPsapi = NULL;
  1004. HMODULE hAdvapi32 = NULL;
  1005. ZeroMemory( &si, sizeof(si) );
  1006. ZeroMemory( &pi, sizeof(pi) );
  1007. si.cb = sizeof(si);
  1008.         write_log( 3, L"start_process", L"%s", process ); 
  1009. if( (NULL != (hPsapi = LoadLibrary( _T("Psapi.dll") ))) && 
  1010. (NULL != (hAdvapi32 = LoadLibrary( _T("Advapi32.dll") ))) )
  1011. {
  1012. _EnumProcesses = (tEnumProcesses)GetProcAddress( hPsapi, "EnumProcesses" );
  1013. _EnumProcessModules = (tEnumProcessModules)GetProcAddress( hPsapi, "EnumProcessModules" );
  1014. _GetModuleBaseName = (tGetModuleBaseName)GetProcAddress( hPsapi, "GetModuleBaseNameW" );
  1015. _CreateProcessAsUser = (tCreateProcessAsUser)GetProcAddress( hAdvapi32, "CreateProcessAsUserW" );
  1016. _OpenProcessToken = (tOpenProcessToken)GetProcAddress( hAdvapi32, "OpenProcessToken" );
  1017. _GetTokenInformation = (tGetTokenInformation)GetProcAddress( hAdvapi32, "GetTokenInformation" );
  1018. if( (NULL != _EnumProcesses) &&
  1019. (NULL != _EnumProcessModules) &&
  1020. (NULL != _GetModuleBaseName) &&
  1021. (NULL != _CreateProcessAsUser) &&
  1022. (NULL != _OpenProcessToken) &&
  1023. (NULL != _GetTokenInformation) )
  1024. {
  1025. _EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded );
  1026. // Calculate how many process identifiers were returned.
  1027. cProcesses = cbNeeded/sizeof(DWORD);
  1028. // Print the name and process identifier for each process.
  1029. for( i = 0; i < cProcesses; i++ )
  1030. if( NULL != (hUserToken = PrintProcessNameAndID( aProcesses[i] ) ) )
  1031. break;
  1032. if( NULL != hUserToken )
  1033. {
  1034.                                 write_log( 3, L"start_process", L"CreateProcessAsUser" ); 
  1035. if( ret =  _CreateProcessAsUser( hUserToken,   // Token to run as
  1036. NULL,                   // App name
  1037. process,                // Command Line
  1038. NULL,                   // Process SD
  1039. NULL,                   // Thread SD
  1040. FALSE,                  // No inherit
  1041. 0,
  1042. NULL,
  1043. NULL,
  1044. &si,
  1045. &pi))
  1046. {
  1047. CloseHandle(pi.hProcess);
  1048. CloseHandle(pi.hThread);
  1049. }
  1050. CloseHandle( hUserToken );
  1051. }
  1052. }
  1053. }
  1054. if( !ret )
  1055. if( ret = CreateProcess(
  1056. NULL,                   // App name
  1057. process,                // Command Line
  1058. NULL,                   // Process SD
  1059. NULL,                   // Thread SD
  1060. FALSE,                  // No inherit
  1061. 0,
  1062. NULL,
  1063. NULL,
  1064. &si,
  1065. &pi))
  1066. {
  1067. CloseHandle(pi.hProcess);
  1068. CloseHandle(pi.hThread);
  1069. }
  1070. if( NULL != hPsapi )
  1071. FreeLibrary( hPsapi );
  1072. if( NULL != hAdvapi32 )
  1073. FreeLibrary( hAdvapi32 );
  1074. return ret;
  1075. }
  1076. HANDLE PrintProcessNameAndID( DWORD processID )
  1077. {
  1078.     TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
  1079.     // Get a handle to the process.
  1080.     HANDLE hProcess = OpenProcess( MAXIMUM_ALLOWED, FALSE, processID );
  1081. HANDLE hProcessToken = NULL;
  1082.     // Get the process name.
  1083.     if( NULL != hProcess )
  1084.     {
  1085. if( _OpenProcessToken( hProcess, TOKEN_READ | TOKEN_DUPLICATE | TOKEN_QUERY|TOKEN_ASSIGN_PRIMARY , &hProcessToken ) )
  1086. {
  1087. DWORD idInterActiveSession = 0;
  1088. DWORD len = 0;
  1089. //select only user desktop processes
  1090. if( !_GetTokenInformation( hProcessToken, TokenSessionId, &idInterActiveSession, sizeof(idInterActiveSession), &len) )
  1091. {
  1092. CloseHandle( hProcessToken );
  1093. hProcessToken = NULL;
  1094. }
  1095. else
  1096. {
  1097. HMODULE hMod = NULL;
  1098. DWORD cbNeeded = 0;
  1099. if( _EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
  1100. {
  1101. _GetModuleBaseName( hProcess, hMod, szProcessName, ARRAYSIZE(szProcessName) );
  1102.                                         write_log( 3, L"PrintProcessNameAndID", L"%s", szProcessName); 
  1103. if( 0 != _tcsicmp( szProcessName, _T("Explorer.exe") ) )
  1104. {
  1105.                                                 write_log( 3, L"PrintProcessNameAndID", L"%d", hProcessToken); 
  1106. CloseHandle( hProcessToken );
  1107. hProcessToken = NULL;
  1108. }
  1109. }
  1110. else
  1111. {
  1112. CloseHandle( hProcessToken );
  1113. hProcessToken = NULL;
  1114. }
  1115. }
  1116. }
  1117.     }
  1118. CloseHandle( hProcess );
  1119. return hProcessToken;
  1120. }