Leaked source code of windows server 2003
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.

567 lines
15 KiB

  1. #include "global.h"
  2. #include "protos.h"
  3. #include "filespyview.h"
  4. #include "fastioview.h"
  5. #include "fsfilterview.h"
  6. #include "leftview.h"
  7. #include "filespyLib.h"
  8. void DisplayIrpFields(CFileSpyView *pView, PLOG_RECORD pLog);
  9. void DisplayFastIoFields(CFastIoView *pView, PLOG_RECORD pLog);
  10. void DisplayFsFilterFields(CFsFilterView *pView, PLOG_RECORD pLog);
  11. DWORD StartFileSpy(void)
  12. {
  13. DWORD nBytesNeeded;
  14. CLeftView *pDriveView;
  15. pDriveView = (CLeftView *) pLeftView;
  16. // Open Service control manager
  17. hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS) ;
  18. hService = OpenServiceW(hSCManager, FILESPY_SERVICE_NAME, FILESPY_SERVICE_ACCESS);
  19. if (hService == NULL)
  20. {
  21. DisplayError(GetLastError());
  22. return 0;
  23. }
  24. if (!QueryServiceStatusEx( hService,
  25. SC_STATUS_PROCESS_INFO,
  26. (UCHAR *)&ServiceInfo,
  27. sizeof(ServiceInfo),
  28. &nBytesNeeded))
  29. {
  30. DisplayError(GetLastError());
  31. CloseServiceHandle(hSCManager);
  32. CloseServiceHandle(hService);
  33. MessageBox(NULL, L"Unable to query Service status information", L"Startup Error", MB_OK|MB_ICONEXCLAMATION);
  34. return 0;
  35. }
  36. if(ServiceInfo.dwCurrentState != SERVICE_RUNNING) {
  37. //
  38. // Service hasn't been started yet, so try to start service
  39. //
  40. if (!StartService(hService, 0, NULL))
  41. {
  42. CloseServiceHandle(hSCManager);
  43. CloseServiceHandle(hService);
  44. MessageBox(NULL, L"Unable to start service", L"Startup Error", MB_OK|MB_ICONSTOP);
  45. return 0;
  46. }
  47. }
  48. //
  49. // Open the device that is used to talk to FileSpy.
  50. //
  51. hDevice = CreateFile( FILESPY_W32_DEVICE_NAME,
  52. GENERIC_READ | GENERIC_WRITE,
  53. 0,
  54. NULL,
  55. OPEN_EXISTING,
  56. FILE_ATTRIBUTE_NORMAL,
  57. NULL );
  58. if (hDevice == INVALID_HANDLE_VALUE)
  59. {
  60. CloseServiceHandle(hSCManager);
  61. CloseServiceHandle(hService);
  62. MessageBox(NULL, L"Unable to open FileSpy device", L"Device Error", MB_OK|MB_ICONSTOP);
  63. return 0;
  64. }
  65. QueryDeviceAttachments();
  66. pDriveView->UpdateImage();
  67. // Create the polling thread
  68. hPollThread = CreateThread(NULL, 0, PollFileSpy, NULL, 0, &nPollThreadId);
  69. return 1;
  70. }
  71. DWORD ShutdownFileSpy(void)
  72. {
  73. USHORT ti;
  74. for (ti = 0; ti < nTotalDrives; ti++)
  75. {
  76. if (VolInfo[ti].bHook)
  77. {
  78. DetachFromDrive( VolInfo[ti].nDriveName );
  79. }
  80. }
  81. CloseHandle(hDevice);
  82. CloseServiceHandle(hService);
  83. CloseServiceHandle(hSCManager);
  84. return 1;
  85. }
  86. BOOL QueryDeviceAttachments(void)
  87. {
  88. WCHAR Buffer[BUFFER_SIZE];
  89. ULONG nBytesReturned;
  90. BOOL nReturnValue;
  91. USHORT ti;
  92. PATTACHED_DEVICE pDevice;
  93. nReturnValue = DeviceIoControl(hDevice, FILESPY_ListDevices, NULL, 0, Buffer, sizeof( Buffer ), &nBytesReturned, NULL);
  94. if (nReturnValue && nBytesReturned)
  95. {
  96. pDevice = (PATTACHED_DEVICE) Buffer;
  97. while ( ((char *)pDevice) < (((char *)Buffer) + nBytesReturned))
  98. {
  99. if (pDevice->LoggingOn)
  100. {
  101. //
  102. // Locate this drive in VolInfo and set its attachment status
  103. //
  104. for (ti = 0; ti < nTotalDrives; ti++)
  105. {
  106. if (VolInfo[ti].nDriveName == towupper( pDevice->DeviceNames[0] ))
  107. {
  108. VolInfo[ti].bHook = 1;
  109. VolInfo[ti].nImage += IMAGE_ATTACHSTART;
  110. }
  111. }
  112. }
  113. pDevice++;
  114. }
  115. }
  116. return nReturnValue;
  117. }
  118. DWORD AttachToDrive(WCHAR cDriveName)
  119. {
  120. WCHAR sDriveString[5];
  121. DWORD nResult, nBytesReturned;
  122. wcscpy(sDriveString, L" :\0");
  123. sDriveString[0] = cDriveName;
  124. nResult = DeviceIoControl( hDevice,
  125. FILESPY_StartLoggingDevice,
  126. sDriveString,
  127. sizeof( sDriveString),
  128. NULL,
  129. 0,
  130. &nBytesReturned,
  131. NULL);
  132. if (!nResult)
  133. {
  134. DisplayError(GetLastError());
  135. return 0;
  136. }
  137. return 1;
  138. }
  139. DWORD DetachFromDrive(WCHAR cDriveName)
  140. {
  141. WCHAR sDriveString[5];
  142. DWORD nResult, nBytesReturned;
  143. wcscpy(sDriveString, L" :\0");
  144. sDriveString[0] = cDriveName;
  145. nResult = DeviceIoControl( hDevice,
  146. FILESPY_StopLoggingDevice,
  147. sDriveString,
  148. sizeof(sDriveString),
  149. NULL,
  150. 0,
  151. &nBytesReturned,
  152. NULL );
  153. if (!nResult)
  154. {
  155. DisplayError(GetLastError());
  156. return 0;
  157. }
  158. return 1;
  159. }
  160. DWORD WINAPI PollFileSpy(LPVOID pParm)
  161. {
  162. char pBuffer[BUFFER_SIZE];
  163. DWORD nBytesReturned, nResult;
  164. PLOG_RECORD pLog;
  165. CFileSpyView *pIrpView;
  166. CFastIoView *pFastView;
  167. CFsFilterView *pFilterView;
  168. UNREFERENCED_PARAMETER( pParm );
  169. pIrpView = (CFileSpyView *) pSpyView;
  170. pFastView = (CFastIoView *) pFastIoView;
  171. pFilterView = (CFsFilterView *) pFsFilterView;
  172. while (1)
  173. {
  174. //
  175. // Start receiving log
  176. //
  177. nResult = DeviceIoControl(hDevice, FILESPY_GetLog, NULL, 0, pBuffer, \
  178. BUFFER_SIZE, &nBytesReturned, NULL);
  179. if (nResult) {
  180. if (nBytesReturned > 0)
  181. {
  182. pLog = (PLOG_RECORD) pBuffer;
  183. while ((CHAR *) pLog < pBuffer + nBytesReturned) {
  184. switch (GET_RECORD_TYPE(pLog))
  185. {
  186. case RECORD_TYPE_IRP:
  187. DisplayIrpFields(pIrpView, pLog);
  188. break;
  189. case RECORD_TYPE_FASTIO:
  190. DisplayFastIoFields(pFastView, pLog);
  191. break;
  192. case RECORD_TYPE_FS_FILTER_OP:
  193. DisplayFsFilterFields(pFilterView, pLog);
  194. break;
  195. default:
  196. //
  197. // Special handling required
  198. break;
  199. }
  200. //
  201. // Move to the next LogRecord
  202. //
  203. pLog = (PLOG_RECORD) (((CHAR *) pLog) + pLog->Length);
  204. }
  205. }
  206. else
  207. {
  208. Sleep( 500 );
  209. }
  210. } else {
  211. return 1;
  212. }
  213. }
  214. return 1;
  215. }
  216. void DisplayIrpFields(CFileSpyView *pView, PLOG_RECORD pLog)
  217. {
  218. INT nItem;
  219. CHAR cStr[NAME_SIZE], cMnStr[NAME_SIZE];
  220. WCHAR sStr[NAME_SIZE], sMnStr[NAME_SIZE];
  221. ULONG nameLength;
  222. if (IRPFilter[pLog->Record.RecordIrp.IrpMajor] == 0)
  223. {
  224. return;
  225. }
  226. else
  227. {
  228. if (nSuppressPagingIO && (pLog->Record.RecordIrp.IrpFlags & IRP_PAGING_IO || pLog->Record.RecordIrp.IrpFlags & IRP_SYNCHRONOUS_PAGING_IO))
  229. {
  230. return;
  231. }
  232. }
  233. nItem = pView->GetListCtrl().GetItemCount();
  234. //
  235. // nItem is 1 based but when we insert/delete items ListCtrl takes 0 based parameter
  236. // so automatically nItem gives an insertion number which is the last item
  237. //
  238. pView->GetListCtrl().InsertItem( nItem,L" " );
  239. pView->GetListCtrl().EnsureVisible( nItem, FALSE );
  240. //
  241. // Sequence number
  242. //
  243. swprintf( sStr, L"%06X ", pLog->SequenceNumber );
  244. pView->GetListCtrl().SetItemText( nItem, 0, sStr );
  245. //
  246. // Irp major and minor strings
  247. //
  248. GetIrpName( pLog->Record.RecordIrp.IrpMajor,
  249. pLog->Record.RecordIrp.IrpMinor,
  250. (ULONG)(ULONG_PTR)pLog->Record.RecordIrp.Argument3,
  251. cStr,
  252. cMnStr);
  253. MultiByteToWideChar(CP_ACP,0,cStr,-1,sStr,sizeof(sStr)/sizeof(WCHAR));
  254. MultiByteToWideChar(CP_ACP,0,cMnStr,-1,sMnStr,sizeof(sStr)/sizeof(WCHAR));
  255. pView->GetListCtrl().SetItemText( nItem, 1, sStr);
  256. pView->GetListCtrl().SetItemText( nItem, 2, sMnStr);
  257. //
  258. // FileObject
  259. //
  260. swprintf( sStr,
  261. L"%08X",
  262. pLog->Record.RecordIrp.FileObject );
  263. pView->GetListCtrl().SetItemText( nItem, 3, sStr );
  264. //
  265. // FileName
  266. //
  267. nameLength = pLog->Length - SIZE_OF_LOG_RECORD;
  268. swprintf( sStr, L"%.*s", nameLength/sizeof(WCHAR), pLog->Name );
  269. pView->GetListCtrl().SetItemText( nItem, 4, sStr );
  270. //
  271. // Process and thread ids
  272. //
  273. swprintf( sStr,
  274. L"%08X:%08X",
  275. pLog->Record.RecordIrp.ProcessId,
  276. pLog->Record.RecordIrp.ThreadId );
  277. pView->GetListCtrl().SetItemText( nItem, 5, sStr );
  278. //
  279. // Originating time
  280. //
  281. GetTimeString( (FILETIME *) &pLog->Record.RecordIrp.OriginatingTime, sStr );
  282. pView->GetListCtrl().SetItemText( nItem, 6, sStr );
  283. //
  284. // Completion time
  285. //
  286. GetTimeString( (FILETIME *) &pLog->Record.RecordIrp.CompletionTime, sStr );
  287. pView->GetListCtrl().SetItemText( nItem, 7, sStr );
  288. //
  289. // Irp flags
  290. //
  291. GetFlagsString( pLog->Record.RecordIrp.IrpFlags, sStr );
  292. pView->GetListCtrl().SetItemText( nItem, 8, sStr );
  293. //
  294. // Sequence number
  295. //
  296. swprintf( sStr,
  297. L"%08lX:%08lX",
  298. pLog->Record.RecordIrp.ReturnStatus,
  299. pLog->Record.RecordIrp.ReturnInformation);
  300. pView->GetListCtrl().SetItemText( nItem, 9, sStr );
  301. }
  302. void DisplayFastIoFields(CFastIoView *pView, PLOG_RECORD pLog)
  303. {
  304. INT nItem;
  305. CHAR cStr[NAME_SIZE];
  306. WCHAR sStr[NAME_SIZE];
  307. ULONG nameLength;
  308. if (FASTIOFilter[pLog->Record.RecordFastIo.Type] == 0)
  309. {
  310. return;
  311. }
  312. nItem = pView->GetListCtrl().GetItemCount();
  313. //
  314. // nItem is 1 based but when we insert/delete items ListCtrl takes 0 based parameter
  315. // so automatically nItem gives an insertion number which is the last item
  316. //
  317. pView->GetListCtrl().InsertItem( nItem, L" " );
  318. pView->GetListCtrl().EnsureVisible( nItem, FALSE );
  319. //
  320. // Sequence number
  321. //
  322. swprintf( sStr, L"%06X ", pLog->SequenceNumber );
  323. pView->GetListCtrl().SetItemText( nItem, 0, sStr );
  324. //
  325. // Fast IO type
  326. //
  327. GetFastioName( pLog->Record.RecordFastIo.Type, cStr );
  328. MultiByteToWideChar(CP_ACP,0,cStr,-1,sStr,sizeof(sStr)/sizeof(WCHAR));
  329. pView->GetListCtrl().SetItemText( nItem, 1, sStr );
  330. //
  331. // FileObject
  332. //
  333. swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.FileObject) ;
  334. pView->GetListCtrl().SetItemText( nItem, 2, sStr );
  335. //
  336. // File name
  337. //
  338. nameLength = pLog->Length - SIZE_OF_LOG_RECORD;
  339. swprintf( sStr, L"%.*s", nameLength/sizeof(WCHAR), pLog->Name );
  340. pView->GetListCtrl().SetItemText( nItem, 3, sStr );
  341. //
  342. // File offset
  343. //
  344. swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.FileOffset );
  345. pView->GetListCtrl().SetItemText( nItem, 4, sStr );
  346. //
  347. // File length
  348. //
  349. swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.Length );
  350. pView->GetListCtrl().SetItemText( nItem, 5, sStr );
  351. //
  352. // Fast IO can wait
  353. //
  354. if (pLog->Record.RecordFastIo.Wait)
  355. {
  356. pView->GetListCtrl().SetItemText(nItem, 6, L"True");
  357. }
  358. else
  359. {
  360. pView->GetListCtrl().SetItemText(nItem, 6, L"False");
  361. }
  362. //
  363. // Thread and process ids
  364. //
  365. swprintf( sStr,
  366. L"%08X:%08X",
  367. pLog->Record.RecordFastIo.ProcessId,
  368. pLog->Record.RecordFastIo.ThreadId );
  369. pView->GetListCtrl().SetItemText( nItem, 7, sStr );
  370. //
  371. // Start time
  372. //
  373. GetTimeString( (FILETIME *) &pLog->Record.RecordFastIo.StartTime,
  374. sStr);
  375. pView->GetListCtrl().SetItemText( nItem, 8, sStr );
  376. //
  377. // Completion time
  378. //
  379. GetTimeString( (FILETIME *) &pLog->Record.RecordFastIo.CompletionTime, sStr );
  380. pView->GetListCtrl().SetItemText( nItem, 9, sStr );
  381. //
  382. // Return status
  383. //
  384. swprintf( sStr, L"%08X", pLog->Record.RecordFastIo.ReturnStatus );
  385. pView->GetListCtrl().SetItemText( nItem, 10, sStr );
  386. }
  387. void DisplayFsFilterFields(CFsFilterView *pView, PLOG_RECORD pLog)
  388. {
  389. INT nItem;
  390. CHAR cStr[NAME_SIZE];
  391. WCHAR sStr[NAME_SIZE];
  392. ULONG nameLength;
  393. nItem = pView->GetListCtrl().GetItemCount();
  394. //
  395. // nItem is 1 based but when we insert/delete items ListCtrl takes 0 based parameter
  396. // so automatically nItem gives an insertion number which is the last item
  397. //
  398. pView->GetListCtrl().InsertItem( nItem, L" " );
  399. pView->GetListCtrl().EnsureVisible( nItem, FALSE );
  400. //
  401. // Sequence number
  402. //
  403. swprintf( sStr, L"%06X ", pLog->SequenceNumber );
  404. pView->GetListCtrl().SetItemText( nItem, 0, sStr );
  405. //
  406. // Fs Filter operation
  407. //
  408. GetFsFilterOperationName( pLog->Record.RecordFsFilterOp.FsFilterOperation, cStr );
  409. MultiByteToWideChar(CP_ACP,0,cStr,-1,sStr,sizeof(sStr)/sizeof(WCHAR));
  410. pView->GetListCtrl().SetItemText( nItem, 1, sStr );
  411. //
  412. // FileObject
  413. //
  414. swprintf( sStr, L"%08X", pLog->Record.RecordFsFilterOp.FileObject );
  415. pView->GetListCtrl().SetItemText( nItem, 2, sStr );
  416. //
  417. // File name
  418. //
  419. nameLength = pLog->Length - SIZE_OF_LOG_RECORD;
  420. swprintf( sStr, L"%.*s", nameLength/sizeof(WCHAR), pLog->Name );
  421. pView->GetListCtrl().SetItemText( nItem, 3, sStr );
  422. //
  423. // Process and thread id
  424. //
  425. swprintf( sStr,
  426. L"%08X:%08X",
  427. pLog->Record.RecordFsFilterOp.ProcessId,
  428. pLog->Record.RecordFsFilterOp.ThreadId );
  429. pView->GetListCtrl().SetItemText( nItem, 4, sStr );
  430. //
  431. // Originating time
  432. //
  433. GetTimeString( (FILETIME *) &pLog->Record.RecordFsFilterOp.OriginatingTime, sStr );
  434. pView->GetListCtrl().SetItemText( nItem, 5, sStr );
  435. //
  436. // Completion time
  437. //
  438. GetTimeString( (FILETIME *) &pLog->Record.RecordFsFilterOp.CompletionTime, sStr );
  439. pView->GetListCtrl().SetItemText( nItem, 6, sStr );
  440. //
  441. // Return status
  442. //
  443. swprintf( sStr, L"%08X", pLog->Record.RecordFsFilterOp.ReturnStatus );
  444. pView->GetListCtrl().SetItemText( nItem, 7, sStr );
  445. }
  446. void GetFlagsString(DWORD nFlags, PWCHAR sStr)
  447. {
  448. swprintf(sStr, L"%08lX ", nFlags);
  449. if (nFlags & IRP_NOCACHE)
  450. {
  451. wcscat( sStr, L"NOCACHE ");
  452. }
  453. if (nFlags & IRP_PAGING_IO)
  454. {
  455. wcscat(sStr, L"PAGEIO ");
  456. }
  457. if (nFlags & IRP_SYNCHRONOUS_API)
  458. {
  459. wcscat(sStr, L"SYNCAPI ");
  460. }
  461. if (nFlags & IRP_SYNCHRONOUS_PAGING_IO)
  462. {
  463. wcscat(sStr, L"SYNCPAGEIO");
  464. }
  465. }
  466. void GetTimeString(FILETIME *pFileTime, PWCHAR sStr)
  467. {
  468. FILETIME LocalFileTime;
  469. SYSTEMTIME SystemTime;
  470. FileTimeToLocalFileTime(pFileTime, &LocalFileTime);
  471. FileTimeToSystemTime(&LocalFileTime, &SystemTime);
  472. swprintf( sStr,
  473. L"%02d:%02d:%02d:%03d",
  474. SystemTime.wHour,
  475. SystemTime.wMinute,
  476. SystemTime.wSecond,
  477. SystemTime.wMilliseconds);
  478. }