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.

392 lines
8.7 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include "psapi.h"
  6. #include <stddef.h>
  7. BOOL
  8. FindDeviceDriver(
  9. LPVOID ImageBase,
  10. PRTL_PROCESS_MODULE_INFORMATION Module
  11. )
  12. /*++
  13. Routine Description:
  14. This function retrieves the full pathname of the executable file
  15. from which the specified module was loaded. The function copies the
  16. null-terminated filename into the buffer pointed to by the
  17. lpFilename parameter.
  18. Routine Description:
  19. ImageBase - Identifies the driver whose executable file name is being
  20. requested.
  21. Return Value:
  22. The return value specifies the actual length of the string copied to
  23. the buffer. A return value of zero indicates an error and extended
  24. error status is available using the GetLastError function.
  25. Arguments:
  26. --*/
  27. {
  28. RTL_PROCESS_MODULES ModuleInformation;
  29. NTSTATUS Status;
  30. DWORD cbModuleInformation;
  31. PRTL_PROCESS_MODULES pModuleInformation;
  32. DWORD i, ReturnedLength;
  33. Status = NtQuerySystemInformation(
  34. SystemModuleInformation,
  35. &ModuleInformation,
  36. sizeof(ModuleInformation),
  37. &ReturnedLength
  38. );
  39. if ( !NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH) ) {
  40. SetLastError( RtlNtStatusToDosError( Status ) );
  41. return(FALSE);
  42. }
  43. cbModuleInformation = offsetof(RTL_PROCESS_MODULES, Modules);
  44. cbModuleInformation += ModuleInformation.NumberOfModules * sizeof(RTL_PROCESS_MODULE_INFORMATION);
  45. pModuleInformation = (PRTL_PROCESS_MODULES) LocalAlloc(LMEM_FIXED, cbModuleInformation);
  46. if (pModuleInformation == NULL) {
  47. return(FALSE);
  48. }
  49. Status = NtQuerySystemInformation(
  50. SystemModuleInformation,
  51. pModuleInformation,
  52. cbModuleInformation,
  53. &ReturnedLength
  54. );
  55. if ( !NT_SUCCESS(Status) ) {
  56. LocalFree((HLOCAL) pModuleInformation);
  57. SetLastError( RtlNtStatusToDosError( Status ) );
  58. return(FALSE);
  59. }
  60. for (i = 0; i < ModuleInformation.NumberOfModules; i++) {
  61. if (pModuleInformation->Modules[i].ImageBase == ImageBase) {
  62. *Module = pModuleInformation->Modules[i];
  63. LocalFree((HLOCAL) pModuleInformation);
  64. return(TRUE);
  65. }
  66. }
  67. LocalFree((HLOCAL) pModuleInformation);
  68. SetLastError(ERROR_INVALID_HANDLE);
  69. return(FALSE);
  70. }
  71. BOOL
  72. WINAPI
  73. EnumDeviceDrivers(
  74. LPVOID *lpImageBase,
  75. DWORD cb,
  76. LPDWORD lpcbNeeded
  77. )
  78. {
  79. RTL_PROCESS_MODULES ModuleInformation;
  80. NTSTATUS Status;
  81. DWORD cbModuleInformation;
  82. PRTL_PROCESS_MODULES pModuleInformation;
  83. DWORD cpvMax;
  84. DWORD i, ReturnedLength;
  85. Status = NtQuerySystemInformation(
  86. SystemModuleInformation,
  87. &ModuleInformation,
  88. sizeof(ModuleInformation),
  89. &ReturnedLength
  90. );
  91. if ( !NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH) ) {
  92. SetLastError( RtlNtStatusToDosError( Status ) );
  93. return(FALSE);
  94. }
  95. cbModuleInformation = offsetof(RTL_PROCESS_MODULES, Modules);
  96. cbModuleInformation += ModuleInformation.NumberOfModules * sizeof(RTL_PROCESS_MODULE_INFORMATION);
  97. pModuleInformation = (PRTL_PROCESS_MODULES) LocalAlloc(LMEM_FIXED, cbModuleInformation);
  98. if (pModuleInformation == NULL) {
  99. return(FALSE);
  100. }
  101. Status = NtQuerySystemInformation(
  102. SystemModuleInformation,
  103. pModuleInformation,
  104. cbModuleInformation,
  105. &ReturnedLength
  106. );
  107. if ( !NT_SUCCESS(Status) ) {
  108. LocalFree((HLOCAL) pModuleInformation);
  109. SetLastError( RtlNtStatusToDosError( Status ) );
  110. return(FALSE);
  111. }
  112. cpvMax = cb / sizeof(LPVOID);
  113. for (i = 0; i < ModuleInformation.NumberOfModules; i++) {
  114. if (i == cpvMax) {
  115. break;
  116. }
  117. try {
  118. lpImageBase[i] = pModuleInformation->Modules[i].ImageBase;
  119. }
  120. except (EXCEPTION_EXECUTE_HANDLER) {
  121. LocalFree((HLOCAL) pModuleInformation);
  122. SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
  123. return(FALSE);
  124. }
  125. }
  126. try {
  127. *lpcbNeeded = ModuleInformation.NumberOfModules * sizeof(LPVOID);
  128. }
  129. except (EXCEPTION_EXECUTE_HANDLER) {
  130. LocalFree((HLOCAL) pModuleInformation);
  131. SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
  132. return(FALSE);
  133. }
  134. LocalFree((HLOCAL) pModuleInformation);
  135. return(TRUE);
  136. }
  137. DWORD
  138. WINAPI
  139. GetDeviceDriverFileNameW(
  140. LPVOID ImageBase,
  141. LPWSTR lpFilename,
  142. DWORD nSize
  143. )
  144. /*++
  145. Routine Description:
  146. This function retrieves the full pathname of the executable file
  147. from which the specified module was loaded. The function copies the
  148. null-terminated filename into the buffer pointed to by the
  149. lpFilename parameter.
  150. Routine Description:
  151. ImageBase - Identifies the driver whose executable file name is being
  152. requested.
  153. lpFilename - Points to the buffer that is to receive the filename.
  154. nSize - Specifies the maximum number of characters to copy. If the
  155. filename is longer than the maximum number of characters
  156. specified by the nSize parameter, it is truncated.
  157. Return Value:
  158. The return value specifies the actual length of the string copied to
  159. the buffer. A return value of zero indicates an error and extended
  160. error status is available using the GetLastError function.
  161. Arguments:
  162. --*/
  163. {
  164. LPSTR lpstr;
  165. DWORD cch;
  166. DWORD cchT;
  167. lpstr = (LPSTR) LocalAlloc(LMEM_FIXED, nSize);
  168. if (lpstr == NULL) {
  169. return(0);
  170. }
  171. cchT = cch = GetDeviceDriverFileNameA(ImageBase, lpstr, nSize);
  172. if (!cch) {
  173. LocalFree((HLOCAL) lpstr);
  174. return 0;
  175. }
  176. if (cchT < nSize) {
  177. //
  178. // Include NULL terminator
  179. //
  180. cchT++;
  181. }
  182. if (!MultiByteToWideChar(CP_ACP, 0, lpstr, cchT, lpFilename, nSize)) {
  183. cch = 0;
  184. }
  185. LocalFree((HLOCAL) lpstr);
  186. return(cch);
  187. }
  188. DWORD
  189. WINAPI
  190. GetDeviceDriverFileNameA(
  191. LPVOID ImageBase,
  192. LPSTR lpFilename,
  193. DWORD nSize
  194. )
  195. {
  196. RTL_PROCESS_MODULE_INFORMATION Module;
  197. DWORD cchT;
  198. DWORD cch;
  199. if (!FindDeviceDriver(ImageBase, &Module)) {
  200. return(0);
  201. }
  202. cch = cchT = (DWORD) (strlen(Module.FullPathName) + 1);
  203. if ( nSize < cch ) {
  204. cch = nSize;
  205. }
  206. CopyMemory(lpFilename, Module.FullPathName, cch);
  207. if (cch == cchT) {
  208. cch--;
  209. }
  210. return(cch);
  211. }
  212. DWORD
  213. WINAPI
  214. GetDeviceDriverBaseNameW(
  215. LPVOID ImageBase,
  216. LPWSTR lpFilename,
  217. DWORD nSize
  218. )
  219. /*++
  220. Routine Description:
  221. This function retrieves the full pathname of the executable file
  222. from which the specified module was loaded. The function copies the
  223. null-terminated filename into the buffer pointed to by the
  224. lpFilename parameter.
  225. Routine Description:
  226. ImageBase - Identifies the driver whose executable file name is being
  227. requested.
  228. lpFilename - Points to the buffer that is to receive the filename.
  229. nSize - Specifies the maximum number of characters to copy. If the
  230. filename is longer than the maximum number of characters
  231. specified by the nSize parameter, it is truncated.
  232. Return Value:
  233. The return value specifies the actual length of the string copied to
  234. the buffer. A return value of zero indicates an error and extended
  235. error status is available using the GetLastError function.
  236. Arguments:
  237. --*/
  238. {
  239. LPSTR lpstr;
  240. DWORD cch;
  241. DWORD cchT;
  242. lpstr = (LPSTR) LocalAlloc(LMEM_FIXED, nSize);
  243. if (lpstr == NULL) {
  244. return(0);
  245. }
  246. cchT = cch = GetDeviceDriverBaseNameA(ImageBase, lpstr, nSize);
  247. if (!cch) {
  248. LocalFree((HLOCAL) lpstr);
  249. return 0;
  250. }
  251. if (cchT < nSize) {
  252. //
  253. // Include NULL terminator
  254. //
  255. cchT++;
  256. }
  257. if (!MultiByteToWideChar(CP_ACP, 0, lpstr, cchT, lpFilename, nSize)) {
  258. cch = 0;
  259. }
  260. LocalFree((HLOCAL) lpstr);
  261. return(cch);
  262. }
  263. DWORD
  264. WINAPI
  265. GetDeviceDriverBaseNameA(
  266. LPVOID ImageBase,
  267. LPSTR lpFilename,
  268. DWORD nSize
  269. )
  270. {
  271. RTL_PROCESS_MODULE_INFORMATION Module;
  272. DWORD cchT;
  273. DWORD cch;
  274. if (!FindDeviceDriver(ImageBase, &Module)) {
  275. return(0);
  276. }
  277. cch = cchT = (DWORD) (strlen(Module.FullPathName + Module.OffsetToFileName) + 1);
  278. if ( nSize < cch ) {
  279. cch = nSize;
  280. }
  281. CopyMemory(lpFilename, Module.FullPathName + Module.OffsetToFileName, cch);
  282. if (cch == cchT) {
  283. cch--;
  284. }
  285. return(cch);
  286. }