Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
7.6 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DNLProc.cpp
  6. * Content: DirectPlay Lobby Process Functions
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/21/00 mjn Created
  12. * 05/08/00 rmt Bug #33616 -- Does not run on Win9X
  13. * 06/28/00 rmt Prefix Bug #38082
  14. * 07/12/00 rmt Fixed lobby launch so only compares first 15 chars (ToolHelp limitation).
  15. * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  16. *@@END_MSINTERNAL
  17. *
  18. ***************************************************************************/
  19. #include "dnlobbyi.h"
  20. //**********************************************************************
  21. // Constant definitions
  22. //**********************************************************************
  23. //**********************************************************************
  24. // Macro definitions
  25. //**********************************************************************
  26. //**********************************************************************
  27. // Structure definitions
  28. //**********************************************************************
  29. //**********************************************************************
  30. // Variable definitions
  31. //**********************************************************************
  32. //**********************************************************************
  33. // Function prototypes
  34. //**********************************************************************
  35. //**********************************************************************
  36. // Function definitions
  37. //**********************************************************************
  38. #define PROCLIST_MAX_PATH 15
  39. #undef DPF_MODNAME
  40. #define DPF_MODNAME "DPLCompareFilenames"
  41. BOOL DPLCompareFilenames(WCHAR *const pwszFilename1,
  42. WCHAR *const pwszFilename2)
  43. {
  44. WCHAR *p1;
  45. WCHAR *p2;
  46. DWORD dwLen;
  47. DNASSERT(pwszFilename1 != NULL);
  48. DNASSERT(pwszFilename2 != NULL);
  49. // Skip path
  50. if ((p1 = wcsrchr(pwszFilename1,L'\\')) == NULL)
  51. p1 = pwszFilename1;
  52. else
  53. p1++;
  54. if ((p2 = wcsrchr(pwszFilename2,L'\\')) == NULL)
  55. p2 = pwszFilename2;
  56. else
  57. p2++;
  58. // if (wcsnicmp(p1,p2,dwLen)==0)
  59. // return(TRUE);
  60. // return(FALSE);
  61. /*dwLen = wcslen(p1);
  62. if (dwLen == 0 || dwLen != wcslen(p2) )
  63. return(FALSE);
  64. while(dwLen)
  65. {
  66. if (towupper(*p1) != towupper(*p2))
  67. return(FALSE);
  68. p1++;
  69. p2++;
  70. dwLen--;
  71. }*/
  72. return (_wcsnicmp(p1,p2,PROCLIST_MAX_PATH) == 0);
  73. }
  74. // ToolHelp Function Pointers.
  75. typedef BOOL (WINAPI *PFNPROCESS32FIRSTW)(HANDLE,LPPROCESSENTRY32W);
  76. typedef BOOL (WINAPI *PFNPROCESS32NEXTW)(HANDLE,LPPROCESSENTRY32W);
  77. #undef DPF_MODNAME
  78. #define DPF_MODNAME "DPLGetProcessList"
  79. HRESULT DPLGetProcessList(WCHAR *const pwszProcess,
  80. DWORD *const prgdwPid,
  81. DWORD *const pdwNumProcesses,
  82. const BOOL bIsUnicodePlatform)
  83. {
  84. HRESULT hResultCode;
  85. BOOL bReturnCode;
  86. HANDLE hSnapshot = NULL; // System snapshot
  87. PROCESSENTRY32 processEntryA;
  88. PROCESSENTRY32W processEntryW;
  89. DWORD dwNumProcesses;
  90. PWSTR pwszExeFile = NULL;
  91. DWORD dwExeFileLen;
  92. HMODULE hKernelDLL = NULL;
  93. PFNPROCESS32FIRSTW pfProcess32FirstW;
  94. PFNPROCESS32NEXTW pfProcess32NextW;
  95. DPFX(DPFPREP, 3,"Parameters: pwszProcess [0x%p], prgdwPid [0x%p], pdwNumProcesses [0x%p]",
  96. pwszProcess,prgdwPid,pdwNumProcesses);
  97. // If we're unicode we have to dynamically load the kernel32 and get the unicode
  98. // entry points. If we're 9X we can link. -Sigh-
  99. if( bIsUnicodePlatform )
  100. {
  101. hKernelDLL = LoadLibraryA( "Kernel32.DLL" );
  102. if(hKernelDLL == NULL)
  103. {
  104. DPFERR("Unable to load Kernel32.DLL");
  105. hResultCode = DPNERR_OUTOFMEMORY;
  106. goto CLEANUP_GETPROCESS;
  107. }
  108. pfProcess32FirstW=(PFNPROCESS32FIRSTW) GetProcAddress( hKernelDLL, "Process32FirstW" );
  109. pfProcess32NextW=(PFNPROCESS32NEXTW) GetProcAddress( hKernelDLL, "Process32NextW" );
  110. if( pfProcess32FirstW == NULL || pfProcess32NextW == NULL )
  111. {
  112. DPFERR( "Error loading unicode entry points" );
  113. hResultCode = DPNERR_GENERIC;
  114. goto CLEANUP_GETPROCESS;
  115. }
  116. }
  117. // Set up to run through process list
  118. hResultCode = DPN_OK;
  119. dwNumProcesses = 0;
  120. hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD,0);
  121. if (hSnapshot < 0)
  122. {
  123. DPFERR("Could not create Snapshot");
  124. hResultCode = DPNERR_OUTOFMEMORY;
  125. goto CLEANUP_GETPROCESS;
  126. }
  127. // Search SnapShot for process list
  128. dwExeFileLen = 0;
  129. pwszExeFile = NULL;
  130. if (bIsUnicodePlatform)
  131. {
  132. processEntryW.dwSize = sizeof(PROCESSENTRY32W);
  133. bReturnCode = (*pfProcess32FirstW)(hSnapshot,&processEntryW);
  134. }
  135. else
  136. {
  137. processEntryA.dwSize = sizeof(PROCESSENTRY32);
  138. bReturnCode = Process32First(hSnapshot,&processEntryA);
  139. }
  140. DPFX(DPFPREP, 7," dwSize cntUsg PID cntThrds PPID PCB Flags Process");
  141. while (bReturnCode)
  142. {
  143. if (bIsUnicodePlatform)
  144. {
  145. pwszExeFile = processEntryW.szExeFile;
  146. }
  147. else
  148. {
  149. // Grow ANSI string as required
  150. if (strlen(reinterpret_cast<CHAR*>(processEntryA.szExeFile)) + 1 > dwExeFileLen)
  151. {
  152. if (pwszExeFile)
  153. DNFree(pwszExeFile);
  154. dwExeFileLen = strlen(reinterpret_cast<CHAR*>(processEntryA.szExeFile)) + 1;
  155. if ((pwszExeFile = static_cast<WCHAR*>
  156. (DNMalloc(dwExeFileLen * sizeof(WCHAR)))) == NULL)
  157. {
  158. DPFERR("Could not allocate filename conversion buffer");
  159. hResultCode = DPNERR_OUTOFMEMORY;
  160. goto CLEANUP_GETPROCESS;
  161. }
  162. }
  163. if( FAILED( STR_jkAnsiToWide( pwszExeFile, processEntryA.szExeFile, dwExeFileLen ) ) )
  164. {
  165. DPFERR( "Error converting ANSI filename to Unicode" );
  166. hResultCode = DPNERR_CONVERSION;
  167. goto CLEANUP_GETPROCESS;
  168. }
  169. }
  170. // Valid process ?
  171. if (DPLCompareFilenames(pwszProcess,pwszExeFile))
  172. {
  173. // Update lpdwProcessIdList array
  174. if (prgdwPid != NULL && dwNumProcesses < *pdwNumProcesses)
  175. {
  176. if( bIsUnicodePlatform )
  177. {
  178. prgdwPid[dwNumProcesses] = processEntryW.th32ProcessID;
  179. }
  180. else
  181. {
  182. prgdwPid[dwNumProcesses] = processEntryA.th32ProcessID;
  183. }
  184. }
  185. else
  186. {
  187. hResultCode = DPNERR_BUFFERTOOSMALL;
  188. }
  189. // Increase valid process count
  190. dwNumProcesses++;
  191. if( bIsUnicodePlatform )
  192. {
  193. DPFX(DPFPREP, 7,"%8lx %4lx %8lx %4lx %8lx %8lx %8lx %s",
  194. processEntryW.dwSize,processEntryW.cntUsage,processEntryW.th32ProcessID,
  195. processEntryW.cntThreads,processEntryW.th32ParentProcessID,
  196. processEntryW.pcPriClassBase,processEntryW.dwFlags,processEntryW.szExeFile);
  197. }
  198. else
  199. {
  200. DPFX(DPFPREP, 7,"%8lx %4lx %8lx %4lx %8lx %8lx %8lx %s",
  201. processEntryA.dwSize,processEntryA.cntUsage,processEntryA.th32ProcessID,
  202. processEntryA.cntThreads,processEntryA.th32ParentProcessID,
  203. processEntryA.pcPriClassBase,processEntryA.dwFlags,processEntryA.szExeFile);
  204. }
  205. }
  206. // Get next process
  207. if (bIsUnicodePlatform)
  208. {
  209. bReturnCode = (*pfProcess32NextW)(hSnapshot,&processEntryW);
  210. }
  211. else
  212. {
  213. bReturnCode = Process32Next(hSnapshot,&processEntryA);
  214. }
  215. }
  216. if( *pdwNumProcesses < dwNumProcesses )
  217. {
  218. hResultCode = DPNERR_BUFFERTOOSMALL;
  219. }
  220. else
  221. {
  222. hResultCode = DPN_OK;
  223. }
  224. *pdwNumProcesses = dwNumProcesses;
  225. CLEANUP_GETPROCESS:
  226. if( hSnapshot != NULL )
  227. CloseHandle( hSnapshot );
  228. if( hKernelDLL != NULL )
  229. FreeLibrary( hKernelDLL );
  230. if (!bIsUnicodePlatform && pwszExeFile)
  231. {
  232. DNFree(pwszExeFile);
  233. }
  234. return hResultCode;
  235. }