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.

1788 lines
49 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. diskperf.c
  5. Abstract:
  6. Program to display and/or update the current value of the Diskperf
  7. driver startup value
  8. Author:
  9. Bob Watson (a-robw) 4 Dec 92
  10. Revision History:
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <ntconfig.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <windows.h>
  20. #include <regstr.h> // for REGSTR_VAL_UPPERFILTERS
  21. #include <tchar.h>
  22. #include <locale.h>
  23. #include "diskperf.h" // include text string id constancts
  24. #pragma warning(disable:4201)
  25. #include <ntdddisk.h>
  26. #pragma warning(pop)
  27. #include <mountmgr.h>
  28. LANGID WINAPI MySetThreadUILanguage(
  29. WORD wReserved);
  30. #define SWITCH_CHAR '-' // is there a system call to get this?
  31. #define ENABLE_CHAR 'Y' // command will be upcased
  32. #define DISABLE_CHAR 'N'
  33. #define ENHANCED_CHAR 'E'
  34. #define LOCAL_CHANGE 2 // number of commands in a local change command
  35. #define REMOTE_CHANGE 3 // number of commands in a remote change command
  36. //
  37. // note these values are arbitrarily based on the whims of the people
  38. // developing the disk drive drivers that belong to the "Filter" group.
  39. //
  40. #define TAG_NORMAL 4 // diskperf starts AFTER ftdisk
  41. #define TAG_ENHANCED 2 // diskperf starts BEFORE ftdisk
  42. #define IRP_STACK_ENABLED 5 // size of IRP stack when diskperf is enabled
  43. #define IRP_STACK_DISABLED 4 // size of IRP stack when diskperf is enabled
  44. #define IRP_STACK_DEFAULT 8 // default IRP stack size in W2K
  45. #define IRP_STACK_NODISKPERF 7
  46. #define DISKPERF_SERVICE_NAME TEXT("DiskPerf")
  47. LPCTSTR lpwszDiskPerfKey = TEXT("SYSTEM\\CurrentControlSet\\Services\\Diskperf");
  48. LPCTSTR lpwszIOSystemKey = TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\I/O System");
  49. LPCTSTR lpwszOsVersionKey = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
  50. LPCTSTR lpwszBuildNumber = TEXT("CurrentBuildNumber");
  51. LPCTSTR lpwszOsVersion = TEXT("CurrentVersion");
  52. #define ENABLE_DISKDRIVE 0x0001
  53. #define ENABLE_VOLUME 0x0002
  54. #define ENABLE_PERMANENT 0x0004
  55. #define ENABLE_PERMANENT_IOCTL 0x0008
  56. LPCTSTR lpwszDiskDriveKey
  57. = TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E967-E325-11CE-BFC1-08002BE10318}");
  58. LPCTSTR lpwszVolumeKey
  59. = TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{71A27CDD-812A-11D0-BEC7-08002BE2092F}");
  60. LPCTSTR lpwszPartmgrKey = TEXT("SYSTEM\\CurrentControlSet\\Services\\Partmgr");
  61. LPCTSTR lpwszEnableCounterValue = TEXT("EnableCounterForIoctl");
  62. ULONG
  63. OpenRegKeys(
  64. IN LPCTSTR lpszMachine,
  65. OUT PHKEY hRegistry,
  66. OUT PHKEY hDiskKey,
  67. OUT PHKEY hVolumeKey,
  68. OUT PHKEY hServiceKey
  69. );
  70. ULONG
  71. SetFilter(
  72. IN HKEY hKey,
  73. IN LPTSTR strFilterString,
  74. IN DWORD dwSize
  75. );
  76. ULONG
  77. GetFilter(
  78. IN HKEY hKey,
  79. OUT LPTSTR strFilterString,
  80. IN DWORD dwSize
  81. );
  82. ULONG
  83. CheckFilter(
  84. IN TCHAR *Buffer
  85. );
  86. ULONG
  87. GetEnableFlag(
  88. IN HKEY hDiskKey,
  89. IN HKEY hVolumeKey
  90. );
  91. ULONG
  92. AddToFilter(
  93. IN HKEY hKey
  94. );
  95. ULONG
  96. RemoveFromFilter(
  97. IN HKEY hKey
  98. );
  99. void
  100. PrintStatus(
  101. IN BOOL bCurrent,
  102. IN ULONG EnableFlag,
  103. IN LPCTSTR cMachineName
  104. );
  105. DWORD __cdecl
  106. Dp_wprintf(
  107. const wchar_t *format,
  108. ...
  109. );
  110. DWORD __cdecl
  111. Dp_fwprintf(
  112. FILE *str,
  113. const wchar_t *format,
  114. ...
  115. );
  116. DWORD __cdecl
  117. Dp_vfwprintf(
  118. FILE *str,
  119. const wchar_t *format,
  120. va_list argptr
  121. );
  122. BOOL
  123. IsBeyondW2K(
  124. IN LPCTSTR lpszMachine,
  125. OUT PDWORD EnableCounter);
  126. ULONG
  127. EnableForIoctl(
  128. IN LPWSTR lpszMachineName
  129. );
  130. ULONG
  131. DisableForIoctl(
  132. IN LPWSTR lpszMachineName,
  133. IN ULONG Request
  134. );
  135. #if DBG
  136. void
  137. DbgPrintMultiSz(
  138. TCHAR *String,
  139. size_t Size
  140. );
  141. #endif
  142. #define REG_TO_DP_INDEX(reg_idx) (DP_LOAD_STATUS_BASE + (\
  143. (reg_idx == SERVICE_BOOT_START) ? DP_BOOT_START : \
  144. (reg_idx == SERVICE_SYSTEM_START) ? DP_SYSTEM_START : \
  145. (reg_idx == SERVICE_AUTO_START) ? DP_AUTO_START : \
  146. (reg_idx == SERVICE_DEMAND_START) ? DP_DEMAND_START : \
  147. (reg_idx == SERVICE_DISABLED) ? DP_NEVER_START : DP_UNDEFINED))
  148. #define MAX_MACHINE_NAME_LEN 32
  149. // command line arguments
  150. #define CMD_SHOW_LOCAL_STATUS 1
  151. #define CMD_DO_COMMAND 2
  152. #define ArgIsSystem(arg) (*(arg) == '\\' ? TRUE : FALSE)
  153. //
  154. // global buffer for help text display strings
  155. //
  156. #define DISP_BUFF_LEN 256
  157. #define NUM_STRING_BUFFS 2
  158. LPCTSTR BlankString = TEXT(" ");
  159. LPCTSTR StartKey = TEXT("Start");
  160. LPCTSTR TagKey = TEXT("Tag");
  161. LPCTSTR EmptyString = TEXT("");
  162. LPCTSTR LargeIrps = TEXT("LargeIrpStackLocations");
  163. HINSTANCE hMod = NULL;
  164. DWORD dwLastError;
  165. LPCTSTR
  166. GetStringResource (
  167. UINT wStringId
  168. )
  169. {
  170. static TCHAR DisplayStringBuffer[NUM_STRING_BUFFS][DISP_BUFF_LEN];
  171. static DWORD dwBuffIndex;
  172. LPTSTR szReturnBuffer;
  173. dwBuffIndex++;
  174. dwBuffIndex %= NUM_STRING_BUFFS;
  175. szReturnBuffer = (LPTSTR)&DisplayStringBuffer[dwBuffIndex][0];
  176. if (!hMod) {
  177. hMod = (HINSTANCE)GetModuleHandle(NULL); // get instance ID of this module;
  178. }
  179. if (hMod) {
  180. if ((LoadString(hMod, wStringId, szReturnBuffer, DISP_BUFF_LEN)) > 0) {
  181. return (LPCTSTR)szReturnBuffer;
  182. } else {
  183. dwLastError = GetLastError();
  184. return EmptyString;
  185. }
  186. } else {
  187. return EmptyString;
  188. }
  189. }
  190. LPCTSTR
  191. GetFormatResource (
  192. UINT wStringId
  193. )
  194. {
  195. static TCHAR TextFormat[DISP_BUFF_LEN];
  196. if (!hMod) {
  197. hMod = (HINSTANCE)GetModuleHandle(NULL); // get instance ID of this module;
  198. }
  199. if (hMod) {
  200. if ((LoadString(hMod, wStringId, TextFormat, DISP_BUFF_LEN)) > 0) {
  201. return (LPCTSTR)&TextFormat[0];
  202. } else {
  203. dwLastError = GetLastError();
  204. return BlankString;
  205. }
  206. } else {
  207. return BlankString;
  208. }
  209. }
  210. VOID
  211. DisplayChangeCmd (
  212. )
  213. {
  214. UINT wID;
  215. TCHAR DisplayStringBuffer[DISP_BUFF_LEN];
  216. if (hMod) {
  217. if ((LoadString(hMod, DP_TEXT_FORMAT, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) {
  218. for (wID=DP_CMD_HELP_START; wID <= DP_CMD_HELP_END; wID++) {
  219. if ((LoadString(hMod, wID, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) {
  220. Dp_wprintf(DisplayStringBuffer);
  221. }
  222. }
  223. }
  224. }
  225. }
  226. VOID
  227. DisplayCmdHelp(
  228. )
  229. {
  230. UINT wID;
  231. TCHAR DisplayStringBuffer[DISP_BUFF_LEN];
  232. if (hMod) {
  233. if ((LoadString(hMod, DP_TEXT_FORMAT, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) {
  234. for (wID=DP_HELP_TEXT_START; wID <= DP_HELP_TEXT_END; wID++) {
  235. if ((LoadString(hMod, wID, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) {
  236. Dp_wprintf(DisplayStringBuffer);
  237. }
  238. }
  239. }
  240. }
  241. DisplayChangeCmd();
  242. }
  243. ULONG
  244. DisplayStatus (
  245. LPTSTR lpszMachine
  246. )
  247. {
  248. ULONG Status;
  249. HKEY hRegistry;
  250. HKEY hDiskPerfKey;
  251. HKEY hDiskKey;
  252. HKEY hVolumeKey;
  253. DWORD dwValue, dwValueSize, dwTag;
  254. TCHAR cMachineName[MAX_MACHINE_NAME_LEN];
  255. PTCHAR pThisWideChar;
  256. PTCHAR pThisChar;
  257. INT iCharCount;
  258. DWORD EnableCounter;
  259. pThisChar = lpszMachine;
  260. pThisWideChar = cMachineName;
  261. iCharCount = 0;
  262. if (pThisChar) { // if machine is not NULL, then copy
  263. while (*pThisChar) {
  264. *pThisWideChar++ = (TCHAR)(*pThisChar++);
  265. if (++iCharCount >= MAX_MACHINE_NAME_LEN) break;
  266. }
  267. *pThisWideChar = 0;
  268. }
  269. if (!lpszMachine) {
  270. LPTSTR strThisSystem = (LPTSTR) GetStringResource(DP_THIS_SYSTEM);
  271. if (strThisSystem != NULL) {
  272. _tcsncpy(cMachineName, strThisSystem, MAX_MACHINE_NAME_LEN);
  273. cMachineName[MAX_MACHINE_NAME_LEN-1] = 0;
  274. }
  275. }
  276. if (IsBeyondW2K(lpszMachine, &EnableCounter)) {
  277. if (EnableCounter) {
  278. PrintStatus(TRUE, ENABLE_PERMANENT_IOCTL, cMachineName);
  279. }
  280. else {
  281. PrintStatus(TRUE, ENABLE_PERMANENT, cMachineName);
  282. }
  283. return ERROR_SUCCESS;
  284. }
  285. Status = OpenRegKeys(
  286. lpszMachine,
  287. &hRegistry,
  288. &hDiskKey,
  289. &hVolumeKey,
  290. &hDiskPerfKey);
  291. if (Status != ERROR_SUCCESS) {
  292. #if DBG
  293. fprintf(stderr,
  294. "DisplayStatus: Cannot open HKLM on target machine: %d\n",
  295. Status);
  296. #endif
  297. Dp_wprintf(GetFormatResource(DP_UNABLE_READ_REGISTRY));
  298. return Status;
  299. }
  300. dwTag = GetEnableFlag(hDiskKey, hVolumeKey);
  301. dwValue = (dwTag == 0) ? SERVICE_DISABLED : SERVICE_BOOT_START;
  302. dwValueSize = sizeof(dwValue);
  303. Status = RegQueryValueEx (
  304. hDiskPerfKey,
  305. StartKey,
  306. NULL,
  307. NULL,
  308. (LPBYTE)&dwValue,
  309. &dwValueSize);
  310. if (Status != ERROR_SUCCESS) {
  311. Dp_wprintf(GetFormatResource(DP_UNABLE_READ_START));
  312. goto DisplayStatusCleanup;
  313. }
  314. PrintStatus(TRUE, dwTag, cMachineName);
  315. DisplayStatusCleanup:
  316. RegCloseKey(hDiskKey);
  317. RegCloseKey(hVolumeKey);
  318. RegCloseKey(hDiskPerfKey);
  319. RegCloseKey(hRegistry);
  320. if (Status != ERROR_SUCCESS) {
  321. Dp_wprintf(GetFormatResource(DP_STATUS_FORMAT), Status);
  322. }
  323. return Status;
  324. }
  325. ULONG
  326. DoChangeCommand (
  327. LPTSTR lpszCommand,
  328. LPTSTR lpszMachine
  329. )
  330. {
  331. // connect to registry on local machine with read/write access
  332. ULONG Status;
  333. HKEY hRegistry;
  334. HKEY hDiskPerfKey;
  335. HKEY hDiskKey;
  336. HKEY hVolumeKey;
  337. DWORD dwValue;
  338. TCHAR cMachineName[MAX_MACHINE_NAME_LEN];
  339. PTCHAR pThisWideChar;
  340. PTCHAR pThisChar;
  341. INT iCharCount;
  342. PTCHAR pCmdChar;
  343. HKEY hIOSystemKey;
  344. DWORD dwDisposition;
  345. DWORD dwIrpValue;
  346. ULONG EnableRequest, DisableRequest;
  347. ULONG EnableFlag, EndFlag = 0;
  348. BOOL bModified, bIrpStackReg;
  349. LONG nIrpStack, nIrpStackReg, nIncrement;
  350. DWORD EnableCounter;
  351. // check command to see if it's valid
  352. _tcsupr (lpszCommand);
  353. pCmdChar = lpszCommand;
  354. dwValue = 0;
  355. EnableRequest = DisableRequest = 0;
  356. if (*pCmdChar++ == SWITCH_CHAR ) {
  357. if (!_tcscmp(pCmdChar, _T("Y")) ||
  358. !_tcscmp(pCmdChar, _T("YA")) ||
  359. !_tcscmp(pCmdChar, _T("YALL"))) {
  360. EnableRequest = ENABLE_DISKDRIVE | ENABLE_VOLUME;
  361. }
  362. else if (!_tcscmp(pCmdChar, _T("N")) ||
  363. !_tcscmp(pCmdChar, _T("NA")) ||
  364. !_tcscmp(pCmdChar, _T("NALL")) ) {
  365. DisableRequest = ENABLE_DISKDRIVE | ENABLE_VOLUME;
  366. }
  367. else if (!_tcscmp(pCmdChar, _T("YD")) ||
  368. !_tcscmp(pCmdChar, _T("YDISK")) ) {
  369. EnableRequest = ENABLE_DISKDRIVE;
  370. }
  371. else if (!_tcscmp(pCmdChar, _T("YV")) ||
  372. !_tcscmp(pCmdChar, _T("YVOLUME")) ) {
  373. EnableRequest = ENABLE_VOLUME;
  374. }
  375. else if (!_tcscmp(pCmdChar, _T("ND")) ||
  376. !_tcscmp(pCmdChar, _T("NDISK")) ) {
  377. DisableRequest = ENABLE_DISKDRIVE;
  378. }
  379. else if (!_tcscmp(pCmdChar, _T("NV")) ||
  380. !_tcscmp(pCmdChar, _T("NVOLUME")) ) {
  381. DisableRequest = ENABLE_VOLUME;
  382. } else {
  383. DisplayCmdHelp();
  384. return ERROR_SUCCESS;
  385. }
  386. } else {
  387. DisplayChangeCmd();
  388. return ERROR_SUCCESS;
  389. }
  390. // if command OK then convert machine to wide string for connection
  391. pThisChar = lpszMachine;
  392. pThisWideChar = cMachineName;
  393. iCharCount = 0;
  394. if (pThisChar) {
  395. while (*pThisChar) {
  396. *pThisWideChar++ = (TCHAR)(*pThisChar++);
  397. if (++iCharCount >= MAX_MACHINE_NAME_LEN) break;
  398. }
  399. *pThisWideChar = 0; // null terminate
  400. }
  401. if (lpszMachine == NULL) {
  402. LPTSTR strThisSystem = (LPTSTR) GetStringResource(DP_THIS_SYSTEM);
  403. if (strThisSystem != NULL) {
  404. _tcsncpy (cMachineName, strThisSystem, MAX_MACHINE_NAME_LEN);
  405. cMachineName[MAX_MACHINE_NAME_LEN-1] = 0;
  406. }
  407. }
  408. if (IsBeyondW2K(lpszMachine, &EnableCounter)) {
  409. if (EnableRequest != 0) {
  410. EnableForIoctl(lpszMachine);
  411. PrintStatus(TRUE, ENABLE_PERMANENT_IOCTL, cMachineName);
  412. }
  413. else if (DisableRequest != 0) {
  414. DisableForIoctl(lpszMachine, DisableRequest);
  415. PrintStatus(TRUE, ENABLE_PERMANENT, cMachineName);
  416. }
  417. return ERROR_SUCCESS;
  418. }
  419. // connect to registry
  420. Status = OpenRegKeys(
  421. lpszMachine,
  422. &hRegistry,
  423. &hDiskKey,
  424. &hVolumeKey,
  425. &hDiskPerfKey);
  426. if (Status != ERROR_SUCCESS) {
  427. #if DBG
  428. fprintf(stderr,
  429. "DoChangeCommand: Cannot connect to registry: Status=%d\n",
  430. Status);
  431. #endif
  432. Dp_wprintf(GetFormatResource(DP_UNABLE_READ_REGISTRY));
  433. return Status;
  434. }
  435. hIOSystemKey = NULL;
  436. nIrpStackReg = 0;
  437. bIrpStackReg = FALSE; // no registry key prior to this
  438. Status = RegCreateKeyEx (
  439. hRegistry,
  440. lpwszIOSystemKey,
  441. 0L, //Reserved
  442. NULL,
  443. 0L, // no special options
  444. KEY_WRITE | KEY_READ, // desired access
  445. NULL, // default security
  446. &hIOSystemKey,
  447. &dwDisposition);
  448. if (Status != ERROR_SUCCESS) {
  449. if ((Status == ERROR_ALREADY_EXISTS) &&
  450. (dwDisposition == REG_OPENED_EXISTING_KEY)) {
  451. // then this key is already in the registry so this is OK
  452. Status = ERROR_SUCCESS;
  453. }
  454. else {
  455. Dp_wprintf(GetFormatResource(DP_UNABLE_READ_REGISTRY));
  456. goto DoChangeCommandCleanup;
  457. }
  458. }
  459. if ( (Status == ERROR_SUCCESS) && (dwDisposition == REG_OPENED_EXISTING_KEY)) {
  460. DWORD dwSize;
  461. dwSize = sizeof(DWORD);
  462. Status = RegQueryValueEx (
  463. hIOSystemKey,
  464. LargeIrps,
  465. 0L,
  466. NULL,
  467. (LPBYTE)&dwIrpValue,
  468. &dwSize);
  469. if (Status == ERROR_SUCCESS) {
  470. #if DBG
  471. fprintf(stderr, "Registry LargeIrpStack=%d\n", dwIrpValue);
  472. #endif
  473. nIrpStackReg = dwIrpValue;
  474. bIrpStackReg = TRUE;
  475. }
  476. }
  477. EnableFlag = GetEnableFlag(hDiskKey, hVolumeKey);
  478. #if DBG
  479. fprintf(stderr, "DoChangeCommand: EnableFlag is %x\n", EnableFlag);
  480. #endif
  481. bModified = FALSE;
  482. nIncrement = 0;
  483. if ( (EnableRequest & ENABLE_DISKDRIVE) &&
  484. !(EnableFlag & ENABLE_DISKDRIVE) ) {
  485. // Turn on filter for disk drives
  486. if (AddToFilter(hDiskKey) == ERROR_SUCCESS) {
  487. bModified = TRUE;
  488. nIncrement++;
  489. }
  490. }
  491. if ( (EnableRequest & ENABLE_VOLUME) &&
  492. !(EnableFlag & ENABLE_VOLUME) ) {
  493. // Turn on filter for volumes
  494. if (AddToFilter(hVolumeKey) == ERROR_SUCCESS) {
  495. bModified = TRUE;
  496. nIncrement++;
  497. }
  498. }
  499. if ( (DisableRequest & ENABLE_DISKDRIVE) &&
  500. (EnableFlag & ENABLE_DISKDRIVE) ) {
  501. // Turn off filter for disk drives
  502. if (RemoveFromFilter(hDiskKey) == ERROR_SUCCESS) {
  503. bModified = TRUE;
  504. nIncrement--;
  505. }
  506. }
  507. if ( (DisableRequest & ENABLE_VOLUME) &&
  508. (EnableFlag & ENABLE_VOLUME) ) {
  509. // Turn off filter for volumes
  510. if (RemoveFromFilter(hVolumeKey) == ERROR_SUCCESS) {
  511. bModified = TRUE;
  512. nIncrement--;
  513. }
  514. }
  515. nIrpStack = 0;
  516. EndFlag = GetEnableFlag(hDiskKey, hVolumeKey);
  517. if (bModified) { // we have modified the registry
  518. dwValue = (EndFlag == 0) ? SERVICE_DISABLED : SERVICE_BOOT_START;
  519. Status = RegSetValueEx(
  520. hDiskPerfKey,
  521. StartKey,
  522. 0L,
  523. REG_DWORD,
  524. (LPBYTE)&dwValue,
  525. sizeof(dwValue));
  526. //
  527. // First update service registry entries
  528. //
  529. if (DisableRequest != 0) {
  530. nIrpStack = nIrpStackReg + nIncrement;
  531. if (EndFlag == 0) {
  532. //
  533. // Turn off service completely
  534. //
  535. // Set Irp stack size to original value or default
  536. if (nIrpStack < IRP_STACK_NODISKPERF)
  537. nIrpStack = IRP_STACK_NODISKPERF;
  538. }
  539. else { // else, there is only one stack left
  540. if (nIrpStack < IRP_STACK_NODISKPERF+1)
  541. nIrpStack = IRP_STACK_NODISKPERF+1;
  542. }
  543. }
  544. else if (EnableRequest != 0) {
  545. nIrpStack = nIrpStackReg + nIncrement;
  546. //
  547. // Set proper Irp stack size
  548. //
  549. if (EndFlag == (ENABLE_DISKDRIVE | ENABLE_VOLUME)) {
  550. if (nIrpStack < IRP_STACK_NODISKPERF+2) // a value is set
  551. nIrpStack = IRP_STACK_NODISKPERF+2;
  552. }
  553. else { // at least one is enabled
  554. if (nIrpStack < IRP_STACK_NODISKPERF+1)
  555. nIrpStack = IRP_STACK_NODISKPERF+1;
  556. }
  557. }
  558. }
  559. else {
  560. //
  561. // No action taken. Should tell the user the state.
  562. //
  563. PrintStatus(TRUE, EndFlag, cMachineName);
  564. Dp_wprintf(GetFormatResource(DP_NOCHANGE));
  565. }
  566. #if DBG
  567. fprintf(stderr, "New LargeIrp is %d\n", nIrpStack);
  568. #endif
  569. if (hIOSystemKey != NULL && Status == ERROR_SUCCESS) {
  570. if (bModified) {
  571. Status = RegSetValueEx (
  572. hIOSystemKey,
  573. LargeIrps,
  574. 0L,
  575. REG_DWORD,
  576. (LPBYTE)&nIrpStack,
  577. sizeof(DWORD));
  578. if (Status == ERROR_SUCCESS) {
  579. PrintStatus(FALSE, EndFlag, cMachineName);
  580. }
  581. else {
  582. Dp_wprintf(GetFormatResource(DP_UNABLE_MODIFY_VALUE));
  583. }
  584. }
  585. RegCloseKey(hIOSystemKey);
  586. }
  587. DoChangeCommandCleanup:
  588. if (hDiskPerfKey != NULL) {
  589. RegCloseKey(hDiskPerfKey);
  590. }
  591. if (hDiskKey != NULL) {
  592. RegCloseKey(hDiskKey);
  593. }
  594. if (hVolumeKey != NULL) {
  595. RegCloseKey(hVolumeKey);
  596. }
  597. if (hRegistry != NULL) {
  598. RegCloseKey(hRegistry);
  599. }
  600. if (Status != ERROR_SUCCESS) {
  601. Dp_wprintf(GetFormatResource(DP_STATUS_FORMAT), Status);
  602. }
  603. return Status;
  604. }
  605. ULONG
  606. OpenRegKeys(
  607. IN LPCTSTR lpszMachine,
  608. OUT PHKEY hRegistry,
  609. OUT PHKEY hDiskKey,
  610. OUT PHKEY hVolumeKey,
  611. OUT PHKEY hServiceKey
  612. )
  613. {
  614. ULONG status;
  615. if (hRegistry == NULL)
  616. return ERROR_INVALID_PARAMETER;
  617. *hRegistry = NULL;
  618. status = RegConnectRegistry(
  619. lpszMachine,
  620. HKEY_LOCAL_MACHINE,
  621. hRegistry);
  622. if (status != ERROR_SUCCESS) {
  623. *hRegistry = NULL;
  624. return status;
  625. }
  626. if (*hRegistry == NULL)
  627. return ERROR_INVALID_PARAMETER; // Avoid PREFIX error
  628. if (hDiskKey) {
  629. *hDiskKey = NULL;
  630. if (status == ERROR_SUCCESS) {
  631. status = RegOpenKeyEx(
  632. *hRegistry,
  633. lpwszDiskDriveKey,
  634. (DWORD) 0,
  635. KEY_SET_VALUE | KEY_QUERY_VALUE,
  636. hDiskKey);
  637. }
  638. }
  639. if (hVolumeKey) {
  640. *hVolumeKey = NULL;
  641. if (status == ERROR_SUCCESS) {
  642. status = RegOpenKeyEx(
  643. *hRegistry,
  644. lpwszVolumeKey,
  645. (DWORD) 0,
  646. KEY_SET_VALUE | KEY_QUERY_VALUE,
  647. hVolumeKey);
  648. }
  649. }
  650. if (hServiceKey) {
  651. *hServiceKey = NULL;
  652. if (status == ERROR_SUCCESS) {
  653. status = RegOpenKeyEx(
  654. *hRegistry,
  655. lpwszDiskPerfKey,
  656. (DWORD) 0,
  657. KEY_SET_VALUE | KEY_QUERY_VALUE,
  658. hServiceKey);
  659. }
  660. }
  661. if ( (status != ERROR_SUCCESS) && (hDiskKey != NULL) ) {
  662. if ((*hDiskKey != NULL) && (*hDiskKey != INVALID_HANDLE_VALUE)) {
  663. RegCloseKey(*hDiskKey);
  664. }
  665. *hDiskKey = NULL;
  666. }
  667. if ( (status != ERROR_SUCCESS) && (hVolumeKey != NULL) ) {
  668. if ((*hVolumeKey != NULL) && (*hVolumeKey != INVALID_HANDLE_VALUE)) {
  669. RegCloseKey(*hVolumeKey);
  670. }
  671. *hVolumeKey = NULL;
  672. }
  673. if ( (status != ERROR_SUCCESS) && (hServiceKey != NULL) ) {
  674. if ((*hServiceKey != NULL) && (*hServiceKey != INVALID_HANDLE_VALUE)) {
  675. RegCloseKey(*hServiceKey);
  676. }
  677. *hServiceKey = NULL;
  678. }
  679. //
  680. // hRegistry and *hRegistry cannot be NULL here
  681. //
  682. if ( (status != ERROR_SUCCESS) && (*hRegistry != INVALID_HANDLE_VALUE)) {
  683. RegCloseKey(*hRegistry);
  684. *hRegistry = NULL;
  685. }
  686. return status;
  687. }
  688. ULONG
  689. SetFilter(
  690. IN HKEY hKey,
  691. IN LPTSTR strFilterString,
  692. IN DWORD dwSize
  693. )
  694. {
  695. ULONG status;
  696. LONG len;
  697. DWORD dwType = REG_MULTI_SZ;
  698. if (hKey == NULL)
  699. return ERROR_BADKEY;
  700. //
  701. // NOTE: Assumes that strFilterString is always MAX_PATH, NULL padded
  702. //
  703. len = dwSize / sizeof(TCHAR);
  704. if (len < 2) {
  705. dwSize = 2 * sizeof(TCHAR);
  706. #if DBG
  707. fprintf(stderr, "SetFilter: Length %d dwSize %d\n", len, dwSize);
  708. #endif
  709. }
  710. else { // ensures 2 null character always
  711. if (strFilterString[len-1] != 0) { // no trailing null
  712. len += 2;
  713. strFilterString[len] = 0;
  714. strFilterString[len+1] = 0;
  715. #if DBG
  716. fprintf(stderr, "SetFilter: New length(+2) %d\n", len);
  717. #endif
  718. }
  719. else if (strFilterString[len-2] != 0) { // only one trailing null
  720. len += 1;
  721. strFilterString[len+1] = 0;
  722. #if DBG
  723. fprintf(stderr, "SetFilter: New length(+1) %d\n", len);
  724. #endif
  725. }
  726. dwSize = len * sizeof(TCHAR);
  727. }
  728. if (len <= 2) {
  729. status = RegDeleteValue(hKey, REGSTR_VAL_UPPERFILTERS);
  730. #if DBG
  731. fprintf(stderr, "Delete status = %d\n", status);
  732. #endif
  733. return status;
  734. }
  735. status = RegSetValueEx(
  736. hKey,
  737. REGSTR_VAL_UPPERFILTERS,
  738. (DWORD) 0,
  739. dwType,
  740. (BYTE*)strFilterString,
  741. dwSize);
  742. #if DBG
  743. if (status != ERROR_SUCCESS) {
  744. _ftprintf(stderr, _T("SetFilter: Cannot query key %s status=%d\n"),
  745. REGSTR_VAL_UPPERFILTERS, status);
  746. }
  747. else {
  748. fprintf(stderr, "SetFilter: ");
  749. DbgPrintMultiSz(strFilterString, dwSize);
  750. fprintf(stderr, "\n");
  751. }
  752. #endif
  753. return status;
  754. }
  755. ULONG
  756. GetFilter(
  757. IN HKEY hKey,
  758. OUT LPTSTR strFilterString,
  759. IN DWORD dwSize
  760. )
  761. // Returns size of strFilterString
  762. {
  763. ULONG status;
  764. if (hKey == NULL)
  765. return ERROR_BADKEY;
  766. status = RegQueryValueEx(
  767. hKey,
  768. REGSTR_VAL_UPPERFILTERS,
  769. NULL,
  770. NULL,
  771. (BYTE*)strFilterString,
  772. &dwSize);
  773. if (status != ERROR_SUCCESS) {
  774. #if DBG
  775. _ftprintf(stderr, _T("GetFilter: Cannot query key %s status=%d\n"),
  776. REGSTR_VAL_UPPERFILTERS, status);
  777. #endif
  778. return 0;
  779. }
  780. #if DBG
  781. else {
  782. fprintf(stderr, "GetFilter: ");
  783. DbgPrintMultiSz(strFilterString, dwSize);
  784. fprintf(stderr, "\n");
  785. }
  786. #endif
  787. return dwSize;
  788. }
  789. ULONG
  790. CheckFilter(TCHAR *Buffer)
  791. {
  792. TCHAR *string = Buffer;
  793. ULONG stringLength, diskperfLen, result;
  794. if (string == NULL)
  795. return 0;
  796. stringLength = (ULONG) _tcslen(string);
  797. diskperfLen = (ULONG) _tcslen(DISKPERF_SERVICE_NAME);
  798. result = FALSE;
  799. while(stringLength != 0) {
  800. if ((diskperfLen == stringLength) &&
  801. (_tcsicmp(string, DISKPERF_SERVICE_NAME) == 0)) {
  802. #if DBG
  803. fprintf(stderr,
  804. "CheckFilter: string found at offset %d\n",
  805. (string - Buffer));
  806. #endif
  807. result = TRUE;
  808. break;
  809. }
  810. string += stringLength + 1;
  811. stringLength = (ULONG) _tcslen(string);
  812. }
  813. return result;
  814. }
  815. ULONG
  816. GetEnableFlag(
  817. IN HKEY hDiskKey,
  818. IN HKEY hVolumeKey
  819. )
  820. // Returns the flags indicating what is enabled
  821. {
  822. ULONG bFlag = 0;
  823. TCHAR strFilter[MAX_PATH+1] = {0};
  824. DWORD dwSize;
  825. dwSize = sizeof(TCHAR) * (MAX_PATH+1);
  826. if (GetFilter(hDiskKey, strFilter, dwSize) > 0) {
  827. if (CheckFilter(strFilter))
  828. bFlag |= ENABLE_DISKDRIVE;
  829. }
  830. #if DBG
  831. else
  832. fprintf(stderr, "GetEnableFlag: No filters for disk drive\n");
  833. #endif
  834. dwSize = sizeof(TCHAR) * (MAX_PATH+1);
  835. if (GetFilter(hVolumeKey, strFilter, dwSize) > 0) {
  836. if (CheckFilter(strFilter))
  837. bFlag |= ENABLE_VOLUME;
  838. }
  839. #if DBG
  840. else
  841. fprintf(stderr, "GetEnableFlag: No filters for volume\n");
  842. #endif
  843. return bFlag;
  844. }
  845. ULONG
  846. AddToFilter(
  847. IN HKEY hKey
  848. )
  849. {
  850. TCHAR *string, buffer[MAX_PATH+1];
  851. ULONG dataLength;
  852. DWORD dwLength, dwSize;
  853. dwSize = sizeof(TCHAR) * MAX_PATH;
  854. RtlZeroMemory(buffer, dwSize + sizeof(TCHAR));
  855. string = buffer;
  856. dataLength = GetFilter(hKey, buffer, dwSize);
  857. dwSize = dataLength;
  858. if (dwSize > (sizeof(TCHAR) * MAX_PATH)) { // just in case
  859. dwSize = sizeof(TCHAR) * MAX_PATH;
  860. }
  861. #if DBG
  862. if (dataLength > 0) {
  863. fprintf(stderr, "AddToFilter: Original string ");
  864. DbgPrintMultiSz(buffer, dataLength);
  865. fprintf(stderr, "\n");
  866. }
  867. else fprintf(stderr, "AddToFilter: Cannot get original string\n");
  868. #endif
  869. dataLength = dataLength / sizeof(TCHAR);
  870. if (dataLength != 0) {
  871. dataLength -= 1;
  872. }
  873. dwLength = (DWORD) _tcslen(DISKPERF_SERVICE_NAME);
  874. if (dataLength < (MAX_PATH-dwLength-1)) {
  875. _tcscpy(&(string[dataLength]), DISKPERF_SERVICE_NAME);
  876. dwSize += (dwLength+1) * sizeof(TCHAR);
  877. }
  878. #if DBG
  879. fprintf(stderr, "AddToFilter: New string ");
  880. DbgPrintMultiSz(buffer, dataLength + _tcslen(DISKPERF_SERVICE_NAME)+1);
  881. fprintf(stderr, "\n");
  882. #endif
  883. return SetFilter(hKey, buffer, dwSize);
  884. }
  885. void
  886. PrintStatus(
  887. IN BOOL bCurrent,
  888. IN ULONG EnableFlag,
  889. IN LPCTSTR cMachineName
  890. )
  891. {
  892. DWORD dwValue;
  893. TCHAR OemDisplayStringBuffer[DISP_BUFF_LEN * 2];
  894. dwValue = (EnableFlag == 0) ? SERVICE_DISABLED : SERVICE_BOOT_START;
  895. if ((EnableFlag & ENABLE_PERMANENT) | (EnableFlag & ENABLE_PERMANENT_IOCTL)) {
  896. _stprintf(OemDisplayStringBuffer,
  897. GetFormatResource(DP_PERMANENT_FORMAT),
  898. cMachineName);
  899. if (EnableFlag & ENABLE_PERMANENT_IOCTL) {
  900. Dp_wprintf(OemDisplayStringBuffer);
  901. _stprintf(OemDisplayStringBuffer,
  902. GetFormatResource(DP_PERMANENT_IOCTL),
  903. cMachineName);
  904. }
  905. else {
  906. Dp_wprintf(OemDisplayStringBuffer);
  907. _stprintf(OemDisplayStringBuffer,
  908. GetFormatResource(DP_PERMANENT_FORMAT1),
  909. cMachineName);
  910. Dp_wprintf(OemDisplayStringBuffer);
  911. _stprintf(OemDisplayStringBuffer,
  912. GetFormatResource(DP_PERMANENT_FORMAT2),
  913. cMachineName);
  914. }
  915. }
  916. else if ( (EnableFlag == (ENABLE_DISKDRIVE | ENABLE_VOLUME)) ||
  917. (EnableFlag == 0) ) {
  918. _stprintf(OemDisplayStringBuffer,
  919. bCurrent ? GetFormatResource (DP_CURRENT_FORMAT1)
  920. : GetFormatResource (DP_NEW_DISKPERF_STATUS1),
  921. cMachineName,
  922. GetStringResource(REG_TO_DP_INDEX(dwValue)));
  923. }
  924. else {
  925. _stprintf (OemDisplayStringBuffer,
  926. bCurrent ? GetFormatResource (DP_CURRENT_FORMAT)
  927. : GetFormatResource (DP_NEW_DISKPERF_STATUS),
  928. (EnableFlag == ENABLE_DISKDRIVE) ?
  929. GetStringResource(DP_PHYSICAL) :
  930. GetStringResource(DP_LOGICAL),
  931. cMachineName,
  932. GetStringResource(REG_TO_DP_INDEX(dwValue)));
  933. }
  934. Dp_wprintf(OemDisplayStringBuffer);
  935. }
  936. ULONG
  937. RemoveFromFilter(
  938. IN HKEY hKey
  939. )
  940. {
  941. TCHAR *string, buffer[MAX_PATH+1];
  942. ULONG dataLength, stringLength, diskperfLen, found;
  943. ULONG removeSize;
  944. dataLength = sizeof(TCHAR) * (MAX_PATH+1); // Compute size first
  945. RtlZeroMemory(buffer, sizeof(TCHAR) * MAX_PATH);
  946. dataLength = GetFilter(hKey, buffer, dataLength);
  947. if (dataLength == 0)
  948. return 0;
  949. #if DBG
  950. fprintf(stderr, "RemoveFromFilter: Original string ");
  951. DbgPrintMultiSz(buffer, dataLength);
  952. fprintf(stderr, "'\n");
  953. #endif
  954. string = (TCHAR *) buffer;
  955. dataLength -= sizeof(TCHAR);
  956. //
  957. // now, find DiskPerf from the entry to remove it
  958. //
  959. stringLength = (ULONG) _tcslen(string);
  960. diskperfLen = (ULONG) _tcslen(DISKPERF_SERVICE_NAME); // includes NULL
  961. removeSize = (diskperfLen+1) * sizeof(TCHAR);
  962. #if DBG
  963. fprintf(stderr, "RemoveFromFilter: diskperfLen=%d removeSize=%d\n",
  964. diskperfLen, removeSize);
  965. #endif
  966. found = FALSE;
  967. while(stringLength != 0 && !found) {
  968. #if DBG
  969. fprintf(stderr,
  970. "RemoveFromFilter: Loop stringLength=%d\n", stringLength);
  971. #endif
  972. if (diskperfLen == stringLength) {
  973. if(_tcsicmp(string, DISKPERF_SERVICE_NAME) == 0) {
  974. //
  975. // found it, so we will remove it right now
  976. //
  977. if (dataLength > removeSize) {
  978. RtlCopyMemory(
  979. string,
  980. string+stringLength+1,
  981. dataLength - removeSize);
  982. RtlZeroMemory(
  983. (PUCHAR)(buffer) + dataLength - removeSize,
  984. removeSize);
  985. }
  986. else {
  987. RtlZeroMemory( buffer, removeSize);
  988. }
  989. found = TRUE;
  990. }
  991. }
  992. // else, try the next entry
  993. string += stringLength + 1;
  994. stringLength = (ULONG) _tcslen(string);
  995. }
  996. dataLength = dataLength + sizeof(TCHAR) - removeSize;
  997. if (dataLength <= MAX_PATH*sizeof(TCHAR))
  998. buffer[dataLength/sizeof(TCHAR)] = 0;
  999. #if DBG
  1000. fprintf(stderr, "RemoveFromFilter: New string ");
  1001. DbgPrintMultiSz(buffer, dataLength);
  1002. fprintf(stderr, "\n");
  1003. #endif
  1004. return SetFilter(hKey, buffer, dataLength);
  1005. }
  1006. /***
  1007. * Dp_wprintf(format) - print formatted data
  1008. *
  1009. * Prints Unicode formatted string to console window using WriteConsoleW.
  1010. * Note: This Dp_wprintf() is used to workaround the problem in c-runtime
  1011. * which looks up LC_CTYPE even for Unicode string.
  1012. *
  1013. */
  1014. DWORD __cdecl
  1015. Dp_wprintf(
  1016. const wchar_t *format,
  1017. ...
  1018. )
  1019. {
  1020. DWORD cchWChar;
  1021. va_list args;
  1022. va_start( args, format );
  1023. cchWChar = Dp_vfwprintf(stdout, format, args);
  1024. va_end(args);
  1025. return cchWChar;
  1026. }
  1027. /***
  1028. * Dp_fwprintf(stream, format) - print formatted data
  1029. *
  1030. * Prints Unicode formatted string to console window using WriteConsoleW.
  1031. * Note: This Dp_fwprintf() is used to workaround the problem in c-runtime
  1032. * which looks up LC_CTYPE even for Unicode string.
  1033. *
  1034. */
  1035. DWORD __cdecl
  1036. Dp_fwprintf(
  1037. FILE *str,
  1038. const wchar_t *format,
  1039. ...
  1040. )
  1041. {
  1042. DWORD cchWChar;
  1043. va_list args;
  1044. va_start( args, format );
  1045. cchWChar = Dp_vfwprintf(str, format, args);
  1046. va_end(args);
  1047. return cchWChar;
  1048. }
  1049. DWORD __cdecl
  1050. Dp_vfwprintf(
  1051. FILE *str,
  1052. const wchar_t *format,
  1053. va_list argptr
  1054. )
  1055. {
  1056. HANDLE hOut;
  1057. if (str == stderr) {
  1058. hOut = GetStdHandle(STD_ERROR_HANDLE);
  1059. }
  1060. else {
  1061. hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  1062. }
  1063. if ((GetFileType(hOut) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR) {
  1064. DWORD cchWChar;
  1065. WCHAR szBufferMessage[1024];
  1066. vswprintf( szBufferMessage, format, argptr );
  1067. cchWChar = (DWORD) wcslen(szBufferMessage);
  1068. WriteConsoleW(hOut, szBufferMessage, cchWChar, &cchWChar, NULL);
  1069. return cchWChar;
  1070. }
  1071. return vfwprintf(str, format, argptr);
  1072. }
  1073. #if DBG
  1074. void
  1075. DbgPrintMultiSz(
  1076. TCHAR *String,
  1077. size_t Size
  1078. )
  1079. {
  1080. size_t len;
  1081. #if DBG
  1082. fprintf(stderr, "%d ", Size);
  1083. #endif
  1084. len = _tcslen(String);
  1085. while (len > 0) {
  1086. _ftprintf(stderr, _T("'%s' "), String);
  1087. String += len+1;
  1088. len = _tcslen(String);
  1089. }
  1090. }
  1091. #endif
  1092. void
  1093. SplitCommandLine(
  1094. LPTSTR CommandLine,
  1095. LPTSTR* pArgv
  1096. )
  1097. {
  1098. LPTSTR arg;
  1099. int i = 0;
  1100. arg = _tcstok( CommandLine, _T(" \t"));
  1101. while( arg != NULL ){
  1102. _tcscpy(pArgv[i++], arg);
  1103. arg = _tcstok(NULL, _T(" \t"));
  1104. }
  1105. }
  1106. int
  1107. __cdecl main(
  1108. int argc,
  1109. char **argv
  1110. )
  1111. {
  1112. LPTSTR *targv,*commandLine;
  1113. ULONG Status = ERROR_SUCCESS;
  1114. int i;
  1115. setlocale(LC_ALL, ".OCP");
  1116. MySetThreadUILanguage(0);
  1117. commandLine = (LPTSTR*)malloc( argc * sizeof(LPTSTR) );
  1118. if (!commandLine)
  1119. exit(1);
  1120. for(i=0;i<argc;i++){
  1121. commandLine[i] = (LPTSTR)malloc( (strlen(argv[i])+1) * sizeof(LPTSTR));
  1122. if (!commandLine[i])
  1123. exit(1);
  1124. }
  1125. SplitCommandLine( GetCommandLine(), commandLine );
  1126. targv = commandLine;
  1127. hMod = (HINSTANCE)GetModuleHandle(NULL); // get instance ID of this module;
  1128. // check for command arguments
  1129. if (argc == CMD_SHOW_LOCAL_STATUS) {
  1130. Status = DisplayStatus(NULL);
  1131. } else if (argc >= CMD_DO_COMMAND) {
  1132. if (ArgIsSystem(targv[1])) {
  1133. Status = DisplayStatus (targv[1]);
  1134. } else { // do change command
  1135. if (argc == LOCAL_CHANGE) {
  1136. DoChangeCommand (targv[1], NULL);
  1137. } else if (argc == REMOTE_CHANGE) {
  1138. DoChangeCommand(targv[1], targv[2]);
  1139. } else {
  1140. DisplayChangeCmd();
  1141. }
  1142. }
  1143. } else {
  1144. DisplayCmdHelp();
  1145. }
  1146. Dp_wprintf(_T("\n"));
  1147. for(i=0;i<argc;i++){
  1148. free(commandLine[i]);
  1149. commandLine[i] = NULL;
  1150. }
  1151. free(commandLine);
  1152. return 0;
  1153. }
  1154. BOOL
  1155. IsBeyondW2K(
  1156. IN LPCTSTR lpszMachine,
  1157. OUT PDWORD EnableCounter
  1158. )
  1159. {
  1160. OSVERSIONINFO OsVersion;
  1161. HKEY hRegistry, hKey;
  1162. TCHAR szBuildNumber[32];
  1163. TCHAR szVersion[32];
  1164. DWORD dwBuildNumber, dwMajor, status, dwSize;
  1165. BOOL bRet = FALSE;
  1166. *EnableCounter = 0;
  1167. hRegistry = INVALID_HANDLE_VALUE;
  1168. if (lpszMachine != NULL) {
  1169. if (*lpszMachine != 0) {
  1170. status = RegConnectRegistry(
  1171. lpszMachine,
  1172. HKEY_LOCAL_MACHINE,
  1173. &hRegistry);
  1174. if (status != ERROR_SUCCESS)
  1175. return FALSE;
  1176. status = RegOpenKeyEx(
  1177. hRegistry,
  1178. lpwszOsVersionKey,
  1179. (DWORD) 0,
  1180. KEY_QUERY_VALUE,
  1181. &hKey);
  1182. if (status != ERROR_SUCCESS) {
  1183. RegCloseKey(hRegistry);
  1184. return FALSE;
  1185. }
  1186. dwSize = sizeof(TCHAR) * 32;
  1187. status = RegQueryValueEx(
  1188. hKey,
  1189. lpwszBuildNumber,
  1190. NULL,
  1191. NULL,
  1192. (BYTE*)szBuildNumber,
  1193. &dwSize);
  1194. if (status != ERROR_SUCCESS) {
  1195. RegCloseKey(hKey);
  1196. RegCloseKey(hRegistry);
  1197. return FALSE;
  1198. }
  1199. status = RegQueryValueEx(
  1200. hKey,
  1201. lpwszOsVersion,
  1202. NULL,
  1203. NULL,
  1204. (BYTE*)szVersion,
  1205. &dwSize);
  1206. if (status != ERROR_SUCCESS) {
  1207. RegCloseKey(hKey);
  1208. RegCloseKey(hRegistry);
  1209. return FALSE;
  1210. }
  1211. RegCloseKey(hKey);
  1212. status = RegOpenKeyEx(
  1213. hRegistry,
  1214. lpwszPartmgrKey,
  1215. (DWORD) 0,
  1216. KEY_QUERY_VALUE,
  1217. &hKey);
  1218. if (status == ERROR_SUCCESS) {
  1219. *EnableCounter = 0;
  1220. status = RegQueryValueEx(
  1221. hKey,
  1222. lpwszEnableCounterValue,
  1223. NULL,
  1224. NULL,
  1225. (BYTE*) EnableCounter,
  1226. &dwSize);
  1227. if ((status != ERROR_SUCCESS) || (dwSize != sizeof(DWORD))) {
  1228. *EnableCounter = 0;
  1229. }
  1230. RegCloseKey(hKey);
  1231. }
  1232. dwBuildNumber = _ttoi(szBuildNumber);
  1233. dwMajor = _ttoi(szVersion);
  1234. if ((dwMajor >= 5) && (dwBuildNumber > 2195)) {
  1235. bRet = TRUE;
  1236. status = RegOpenKeyEx(
  1237. hRegistry,
  1238. lpwszPartmgrKey,
  1239. (DWORD) 0,
  1240. KEY_QUERY_VALUE,
  1241. &hKey);
  1242. if (status == ERROR_SUCCESS) {
  1243. status = RegQueryValueEx(
  1244. hKey,
  1245. lpwszEnableCounterValue,
  1246. NULL,
  1247. NULL,
  1248. (BYTE*) EnableCounter,
  1249. &dwSize);
  1250. if ((status != ERROR_SUCCESS) || (dwSize != sizeof(DWORD))) {
  1251. *EnableCounter = 0;
  1252. }
  1253. RegCloseKey(hKey);
  1254. }
  1255. }
  1256. if (hRegistry != INVALID_HANDLE_VALUE) {
  1257. RegCloseKey(hRegistry);
  1258. }
  1259. }
  1260. }
  1261. else {
  1262. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1263. if (GetVersionEx(&OsVersion)) {
  1264. if ((OsVersion.dwMajorVersion >= 5) &&
  1265. (OsVersion.dwMinorVersion > 0) &&
  1266. (OsVersion.dwBuildNumber > 2195))
  1267. return TRUE;
  1268. }
  1269. }
  1270. return FALSE;
  1271. }
  1272. ULONG
  1273. EnableForIoctl(
  1274. IN LPWSTR lpszMachineName
  1275. )
  1276. {
  1277. DWORD status;
  1278. HKEY hRegistry, hKey;
  1279. DWORD dwValue = 1;
  1280. hRegistry = NULL;
  1281. status = RegConnectRegistry(
  1282. lpszMachineName,
  1283. HKEY_LOCAL_MACHINE,
  1284. &hRegistry);
  1285. if (status != ERROR_SUCCESS)
  1286. return status;
  1287. if (hRegistry == NULL)
  1288. return ERROR_INVALID_PARAMETER;
  1289. hKey = NULL;
  1290. status = RegOpenKeyEx(
  1291. hRegistry,
  1292. lpwszPartmgrKey,
  1293. (DWORD) 0,
  1294. KEY_SET_VALUE | KEY_QUERY_VALUE,
  1295. &hKey);
  1296. if (status != ERROR_SUCCESS) {
  1297. RegCloseKey(hRegistry);
  1298. return status;
  1299. }
  1300. status = RegSetValueEx(
  1301. hKey,
  1302. lpwszEnableCounterValue,
  1303. 0L,
  1304. REG_DWORD,
  1305. (LPBYTE)&dwValue,
  1306. sizeof(dwValue));
  1307. RegCloseKey(hKey);
  1308. RegCloseKey(hRegistry);
  1309. return 0;
  1310. }
  1311. ULONG
  1312. DisableForIoctl(
  1313. IN LPWSTR lpszMachineName,
  1314. IN ULONG Request
  1315. )
  1316. {
  1317. ULONG nDisk, i;
  1318. SYSTEM_DEVICE_INFORMATION DeviceInfo;
  1319. NTSTATUS status;
  1320. UNICODE_STRING UnicodeName;
  1321. OBJECT_ATTRIBUTES ObjectAttributes;
  1322. IO_STATUS_BLOCK IoStatus;
  1323. WCHAR devname[MAX_PATH+1];
  1324. PWCHAR s;
  1325. HANDLE PartitionHandle, MountMgrHandle, VolumeHandle;
  1326. DWORD ReturnedBytes;
  1327. HKEY hRegistry, hKey;
  1328. status = RegConnectRegistry(
  1329. lpszMachineName,
  1330. HKEY_LOCAL_MACHINE,
  1331. &hRegistry);
  1332. if (status != ERROR_SUCCESS)
  1333. return status;
  1334. if (hRegistry == NULL)
  1335. return ERROR_INVALID_PARAMETER;
  1336. status = RegOpenKeyEx(
  1337. hRegistry,
  1338. lpwszPartmgrKey,
  1339. (DWORD) 0,
  1340. KEY_SET_VALUE | KEY_QUERY_VALUE,
  1341. &hKey);
  1342. if (status != ERROR_SUCCESS) {
  1343. RegCloseKey(hRegistry);
  1344. return status;
  1345. }
  1346. RegDeleteValue(hKey, lpwszEnableCounterValue);
  1347. RegCloseKey(hKey);
  1348. RegCloseKey(hRegistry);
  1349. if (!(Request & ENABLE_DISKDRIVE)) goto DisableVolume;
  1350. status = NtQuerySystemInformation(SystemDeviceInformation, &DeviceInfo, sizeof(DeviceInfo), NULL);
  1351. if (!NT_SUCCESS(status)) {
  1352. return 0;
  1353. }
  1354. nDisk = DeviceInfo.NumberOfDisks;
  1355. // for each physical disk
  1356. for (i = 0; i < nDisk; i++) {
  1357. swprintf(devname, L"\\Device\\Harddisk%d\\Partition0", i);
  1358. RtlInitUnicodeString(&UnicodeName, devname);
  1359. InitializeObjectAttributes(
  1360. &ObjectAttributes,
  1361. &UnicodeName,
  1362. OBJ_CASE_INSENSITIVE,
  1363. NULL,
  1364. NULL
  1365. );
  1366. // opening a partition handle for physical drives
  1367. status = NtOpenFile(
  1368. &PartitionHandle,
  1369. FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  1370. &ObjectAttributes,
  1371. &IoStatus,
  1372. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1373. FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
  1374. );
  1375. if ( !NT_SUCCESS(status) ) {
  1376. continue;
  1377. }
  1378. // sending IOCTL over to Partition Handle
  1379. if (!DeviceIoControl(PartitionHandle,
  1380. IOCTL_DISK_PERFORMANCE_OFF,
  1381. NULL,
  1382. 0,
  1383. NULL,
  1384. 0,
  1385. &ReturnedBytes,
  1386. NULL
  1387. )) {
  1388. #if DBG
  1389. printf("IOCTL failed for %ws\n", devname);
  1390. #endif
  1391. }
  1392. NtClose(PartitionHandle);
  1393. }
  1394. DisableVolume:
  1395. if (!(Request | ENABLE_VOLUME)) {
  1396. return 0;
  1397. }
  1398. MountMgrHandle = FindFirstVolumeW(devname, MAX_PATH);
  1399. if (MountMgrHandle == NULL) {
  1400. #if DBG
  1401. printf("Cannot find first volume\n");
  1402. #endif
  1403. return 0;
  1404. }
  1405. i = (ULONG) wcslen(devname);
  1406. if (i > 0) {
  1407. s = (PWCHAR) &devname[i-1];
  1408. if (*s == L'\\') {
  1409. *s = UNICODE_NULL;
  1410. }
  1411. }
  1412. VolumeHandle = CreateFile(devname, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
  1413. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
  1414. if (VolumeHandle != INVALID_HANDLE_VALUE) {
  1415. #if DBG
  1416. printf("Opened with success\n");
  1417. #endif
  1418. // sending IOCTL over to a volume handle
  1419. if (!DeviceIoControl(VolumeHandle,
  1420. IOCTL_DISK_PERFORMANCE_OFF,
  1421. NULL,
  1422. 0,
  1423. NULL,
  1424. 0,
  1425. &ReturnedBytes,
  1426. NULL
  1427. )) {
  1428. #if DBG
  1429. printf("IOCTL failed for %ws\n", devname);
  1430. #endif
  1431. }
  1432. CloseHandle(VolumeHandle);
  1433. }
  1434. while (FindNextVolumeW(MountMgrHandle, devname, MAX_PATH)) {
  1435. i = (ULONG) wcslen(devname);
  1436. if (i > 0) {
  1437. s = (PWCHAR) &devname[i-1];
  1438. if (*s == L'\\') {
  1439. *s = UNICODE_NULL;
  1440. }
  1441. }
  1442. else {
  1443. continue;
  1444. }
  1445. VolumeHandle = CreateFile(devname, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
  1446. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
  1447. if (VolumeHandle != INVALID_HANDLE_VALUE) {
  1448. #if DBG
  1449. printf("Opened with success\n");
  1450. #endif
  1451. if (!DeviceIoControl(VolumeHandle,
  1452. IOCTL_DISK_PERFORMANCE_OFF,
  1453. NULL,
  1454. 0,
  1455. NULL,
  1456. 0,
  1457. &ReturnedBytes,
  1458. NULL
  1459. )) {
  1460. #if DBG
  1461. printf("IOCTL failed for %ws\n", devname);
  1462. #endif
  1463. }
  1464. CloseHandle(VolumeHandle);
  1465. }
  1466. }
  1467. FindVolumeClose(MountMgrHandle);
  1468. return 0;
  1469. }
  1470. ////////////////////////////////////////////////////////////////////////////
  1471. //
  1472. // MySetThreadUILanguage
  1473. //
  1474. // This routine sets the thread UI language based on the console codepage.
  1475. //
  1476. // 9-29-00 WeiWu Created.
  1477. // Copied from Base\Win32\Winnls so that it works in W2K as well
  1478. ////////////////////////////////////////////////////////////////////////////
  1479. LANGID WINAPI MySetThreadUILanguage(
  1480. WORD wReserved)
  1481. {
  1482. //
  1483. // Cache system locale and CP info
  1484. //
  1485. LCID s_lidSystem = 0;
  1486. ULONG s_uiSysCp = 0;
  1487. ULONG s_uiSysOEMCp = 0;
  1488. ULONG uiUserUICp = 0;
  1489. ULONG uiUserUIOEMCp = 0;
  1490. WCHAR szData[16];
  1491. UNICODE_STRING ucStr;
  1492. LANGID lidUserUI = GetUserDefaultUILanguage();
  1493. LCID lcidThreadOld = GetThreadLocale();
  1494. //
  1495. // Set default thread locale to EN-US
  1496. //
  1497. // This allow us to fall back to English UI to avoid trashed characters
  1498. // when console doesn't meet the criteria of rendering native UI.
  1499. //
  1500. LCID lcidThread = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
  1501. UINT uiConsoleCp = GetConsoleOutputCP();
  1502. UNREFERENCED_PARAMETER(wReserved);
  1503. //
  1504. // Make sure nobody uses it yet
  1505. //
  1506. ASSERT(wReserved == 0);
  1507. //
  1508. // Get cached system locale and CP info.
  1509. //
  1510. if (!s_uiSysCp)
  1511. {
  1512. LCID lcidSystem = GetSystemDefaultLCID();
  1513. if (lcidSystem)
  1514. {
  1515. //
  1516. // Get ANSI CP
  1517. //
  1518. GetLocaleInfoW(lcidSystem, LOCALE_IDEFAULTANSICODEPAGE, szData, sizeof(szData)/sizeof(WCHAR));
  1519. RtlInitUnicodeString(&ucStr, szData);
  1520. RtlUnicodeStringToInteger(&ucStr, 10, &uiUserUICp);
  1521. //
  1522. // Get OEM CP
  1523. //
  1524. GetLocaleInfoW(lcidSystem, LOCALE_IDEFAULTCODEPAGE, szData, sizeof(szData)/sizeof(WCHAR));
  1525. RtlInitUnicodeString(&ucStr, szData);
  1526. RtlUnicodeStringToInteger(&ucStr, 10, &s_uiSysOEMCp);
  1527. //
  1528. // Cache system primary langauge
  1529. //
  1530. s_lidSystem = PRIMARYLANGID(LANGIDFROMLCID(lcidSystem));
  1531. }
  1532. }
  1533. //
  1534. // Don't cache user UI language and CP info, UI language can be changed without system reboot.
  1535. //
  1536. if (lidUserUI)
  1537. {
  1538. GetLocaleInfoW(MAKELCID(lidUserUI,SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szData, sizeof(szData)/sizeof(WCHAR));
  1539. RtlInitUnicodeString(&ucStr, szData);
  1540. RtlUnicodeStringToInteger(&ucStr, 10, &uiUserUICp);
  1541. GetLocaleInfoW(MAKELCID(lidUserUI,SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, szData, sizeof(szData)/sizeof(WCHAR));
  1542. RtlInitUnicodeString(&ucStr, szData);
  1543. RtlUnicodeStringToInteger(&ucStr, 10, &uiUserUIOEMCp);
  1544. }
  1545. //
  1546. // Complex scripts cannot be rendered in the console, so we
  1547. // force the English (US) resource.
  1548. //
  1549. if (uiConsoleCp &&
  1550. s_lidSystem != LANG_ARABIC &&
  1551. s_lidSystem != LANG_HEBREW &&
  1552. s_lidSystem != LANG_VIETNAMESE &&
  1553. s_lidSystem != LANG_THAI)
  1554. {
  1555. //
  1556. // Use UI language for console only when console CP, system CP and UI language CP match.
  1557. //
  1558. if ((uiConsoleCp == s_uiSysCp || uiConsoleCp == s_uiSysOEMCp) &&
  1559. (uiConsoleCp == uiUserUICp || uiConsoleCp == uiUserUIOEMCp))
  1560. {
  1561. lcidThread = MAKELCID(lidUserUI, SORT_DEFAULT);
  1562. }
  1563. }
  1564. //
  1565. // Set the thread locale if it's different from the currently set
  1566. // thread locale.
  1567. //
  1568. if ((lcidThread != lcidThreadOld) && (!SetThreadLocale(lcidThread)))
  1569. {
  1570. lcidThread = lcidThreadOld;
  1571. }
  1572. //
  1573. // Return the thread locale that was set.
  1574. //
  1575. return (LANGIDFROMLCID(lcidThread));
  1576. }