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.

513 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1998
  6. //
  7. // File: scsiprop.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "propp.h"
  11. #include "scsiprop.h"
  12. #include <regstr.h>
  13. const DWORD ScsiHelpIDs[]=
  14. {
  15. IDC_SCSI_TAGGED_QUEUING, idh_devmgr_scsi_tagged_queuing, //Use tagged queuing check box
  16. IDC_SCSI_SYNCHONOUS_TX, idh_devmgr_scsi_transfersynch, //Make transfer synchronous check box.
  17. 0, 0
  18. };
  19. //==========================================================================
  20. // Local Function Prototypes
  21. //==========================================================================
  22. BOOL IsUserAdmin();
  23. INT_PTR
  24. ScsiDialogProc(
  25. HWND Dialog,
  26. UINT Message,
  27. WPARAM WParam,
  28. LPARAM LParam
  29. );
  30. BOOL
  31. ScsiDialogCallback(
  32. HWND Dialog,
  33. UINT Message,
  34. LPPROPSHEETPAGE Page
  35. );
  36. BOOL
  37. ScsiCheckDriveType (
  38. HDEVINFO DeviceInfoSet,
  39. PSP_DEVINFO_DATA DeviceInfoData);
  40. BOOL CALLBACK
  41. ScsiPropPageProvider(
  42. PSP_PROPSHEETPAGE_REQUEST Request,
  43. LPFNADDPROPSHEETPAGE AddPageRoutine,
  44. LPARAM AddPageContext
  45. )
  46. {
  47. BOOL result;
  48. BOOL isScsi;
  49. PROPSHEETPAGE page;
  50. HPROPSHEETPAGE pageHandle;
  51. PSCSI_PAGE_DATA data;
  52. if(Request->cbSize != sizeof(SP_PROPSHEETPAGE_REQUEST)) {
  53. return FALSE;
  54. }
  55. switch(Request->PageRequested) {
  56. case SPPSR_ENUM_ADV_DEVICE_PROPERTIES: {
  57. result = TRUE;
  58. break;
  59. }
  60. case SPPSR_ENUM_BASIC_DEVICE_PROPERTIES: {
  61. result = FALSE;
  62. break;
  63. }
  64. default: {
  65. result = FALSE;
  66. break;
  67. }
  68. }
  69. if (!IsUserAdmin()) {
  70. result = FALSE;
  71. }
  72. if(result) {
  73. isScsi = ScsiCheckDriveType(Request->DeviceInfoSet,
  74. Request->DeviceInfoData);
  75. if (isScsi) {
  76. data = LocalAlloc(0, sizeof(SCSI_PAGE_DATA));
  77. if(data == NULL) {
  78. return FALSE;
  79. }
  80. data->DeviceInfoSet = Request->DeviceInfoSet;
  81. data->DeviceInfoData = Request->DeviceInfoData;
  82. //
  83. // At this point we've determined that this is a request for pages we
  84. // provide. Instantiate the pages and call the AddPage routine to put
  85. // them install them.
  86. //
  87. memset(&page, 0, sizeof(PROPSHEETPAGE));
  88. page.dwSize = sizeof(PROPSHEETPAGE);
  89. page.dwFlags = PSP_USECALLBACK;
  90. page.hInstance = ModuleInstance;
  91. page.pszTemplate = MAKEINTRESOURCE(ID_SCSI_PROPPAGE);
  92. page.pfnDlgProc = ScsiDialogProc;
  93. page.pfnCallback = ScsiDialogCallback;
  94. page.lParam = (LPARAM) data;
  95. pageHandle = CreatePropertySheetPage(&page);
  96. if(pageHandle == FALSE) {
  97. return FALSE;
  98. }
  99. result = AddPageRoutine(pageHandle, AddPageContext);
  100. }
  101. }
  102. return result;
  103. }
  104. BOOL
  105. ScsiContextMenu(
  106. HWND HwndControl,
  107. WORD Xpos,
  108. WORD Ypos
  109. )
  110. {
  111. WinHelp(HwndControl,
  112. _T("devmgr.hlp"),
  113. HELP_CONTEXTMENU,
  114. (ULONG_PTR) ScsiHelpIDs);
  115. return FALSE;
  116. }
  117. void
  118. ScsiHelp(
  119. HWND ParentHwnd,
  120. LPHELPINFO HelpInfo
  121. )
  122. {
  123. if (HelpInfo->iContextType == HELPINFO_WINDOW) {
  124. WinHelp((HWND) HelpInfo->hItemHandle,
  125. _T("devmgr.hlp"),
  126. HELP_WM_HELP,
  127. (ULONG_PTR) ScsiHelpIDs);
  128. }
  129. }
  130. UINT
  131. SetRequestFlagsMask(PSCSI_PAGE_DATA data)
  132. {
  133. HKEY hKey;
  134. DWORD requestFlagsMask;
  135. DWORD len, type;
  136. if (INVALID_HANDLE_VALUE ==
  137. (hKey = SetupDiOpenDevRegKey(data->DeviceInfoSet,
  138. data->DeviceInfoData,
  139. DICS_FLAG_GLOBAL,
  140. 0,
  141. DIREG_DEV,
  142. KEY_ALL_ACCESS))) {
  143. return GetLastError();
  144. }
  145. len = sizeof(DWORD);
  146. if (ERROR_SUCCESS != RegQueryValueEx(hKey,
  147. TEXT("RequestFlagsMask"),
  148. NULL,
  149. &type,
  150. (LPBYTE) &requestFlagsMask,
  151. &len)) {
  152. //
  153. // Assume key wasn't there - set to 0;
  154. //
  155. requestFlagsMask = 0;
  156. }
  157. len = sizeof(DWORD);
  158. if (data->TagQueuingCurState) {
  159. requestFlagsMask |= 0x2;
  160. } else {
  161. requestFlagsMask &= ~(DWORD)0x2;
  162. }
  163. if (ERROR_SUCCESS != RegSetValueEx(hKey,
  164. TEXT("RequestFlagsMask"),
  165. 0,
  166. REG_DWORD,
  167. (LPBYTE) &requestFlagsMask,
  168. len)) {
  169. RegCloseKey(hKey);
  170. return GetLastError();
  171. }
  172. RegCloseKey(hKey);
  173. return ERROR_SUCCESS;
  174. }
  175. UINT
  176. SetDefaultRequestFlags(PSCSI_PAGE_DATA data)
  177. {
  178. HKEY hKey;
  179. DWORD DefaultRequestFlags;
  180. DWORD len, type;
  181. if (INVALID_HANDLE_VALUE ==
  182. (hKey = SetupDiOpenDevRegKey(data->DeviceInfoSet,
  183. data->DeviceInfoData,
  184. DICS_FLAG_GLOBAL,
  185. 0,
  186. DIREG_DEV,
  187. KEY_ALL_ACCESS))) {
  188. return GetLastError();
  189. }
  190. len = sizeof(DWORD);
  191. if (ERROR_SUCCESS != RegQueryValueEx(hKey,
  192. TEXT("DefaultRequestFlags"),
  193. NULL,
  194. &type,
  195. (LPBYTE) &DefaultRequestFlags,
  196. &len)) {
  197. //
  198. // Assume key wasn't there - set to 0;
  199. //
  200. DefaultRequestFlags = 0;
  201. }
  202. len = sizeof(DWORD);
  203. if (data->SyncTransCurState) {
  204. DefaultRequestFlags |= 0x8;
  205. } else {
  206. DefaultRequestFlags &= ~(DWORD)0x8;
  207. }
  208. if (ERROR_SUCCESS != RegSetValueEx(hKey,
  209. TEXT("DefaultRequestFlags"),
  210. 0,
  211. REG_DWORD,
  212. (LPBYTE) &DefaultRequestFlags,
  213. len)) {
  214. RegCloseKey(hKey);
  215. return GetLastError();
  216. }
  217. RegCloseKey(hKey);
  218. return ERROR_SUCCESS;
  219. }
  220. UINT
  221. GetRequestFlagsMask(PSCSI_PAGE_DATA data)
  222. {
  223. HKEY hKey;
  224. DWORD requestFlagsMask;
  225. DWORD len, type;
  226. if (INVALID_HANDLE_VALUE ==
  227. (hKey = SetupDiOpenDevRegKey(data->DeviceInfoSet,
  228. data->DeviceInfoData,
  229. DICS_FLAG_GLOBAL,
  230. 0,
  231. DIREG_DEV,
  232. KEY_ALL_ACCESS))) {
  233. data->TagQueuingCurState = FALSE;
  234. data->TagQueuingOrigState = FALSE;
  235. return GetLastError();
  236. }
  237. len = sizeof(DWORD);
  238. if (ERROR_SUCCESS != RegQueryValueEx(hKey,
  239. TEXT("RequestFlagsMask"),
  240. NULL,
  241. &type,
  242. (LPBYTE) &requestFlagsMask,
  243. &len)) {
  244. data->TagQueuingCurState = FALSE;
  245. data->TagQueuingOrigState = FALSE;
  246. RegCloseKey(hKey);
  247. return GetLastError();
  248. }
  249. RegCloseKey(hKey);
  250. if (2 & requestFlagsMask) {
  251. data->TagQueuingCurState = TRUE;
  252. data->TagQueuingOrigState = TRUE;
  253. } else {
  254. data->TagQueuingCurState = FALSE;
  255. data->TagQueuingOrigState = FALSE;
  256. }
  257. return ERROR_SUCCESS;
  258. }
  259. UINT
  260. GetDefaultRequestFlags(PSCSI_PAGE_DATA data)
  261. {
  262. HKEY hKey;
  263. DWORD defaultRequestFlags;
  264. DWORD len, type;
  265. if (INVALID_HANDLE_VALUE ==
  266. (hKey = SetupDiOpenDevRegKey(data->DeviceInfoSet,
  267. data->DeviceInfoData,
  268. DICS_FLAG_GLOBAL,
  269. 0,
  270. DIREG_DEV,
  271. KEY_ALL_ACCESS))) {
  272. data->SyncTransOrigState = FALSE;
  273. data->SyncTransCurState = FALSE;
  274. return GetLastError();
  275. }
  276. len = sizeof(DWORD);
  277. if (ERROR_SUCCESS != RegQueryValueEx(hKey,
  278. TEXT("DefaultRequestFlags"),
  279. NULL,
  280. &type,
  281. (LPBYTE) &defaultRequestFlags,
  282. &len)) {
  283. data->SyncTransOrigState = FALSE;
  284. data->SyncTransCurState = FALSE;
  285. RegCloseKey(hKey);
  286. return GetLastError();
  287. }
  288. RegCloseKey(hKey);
  289. if (8 & defaultRequestFlags) {
  290. data->SyncTransOrigState = TRUE;
  291. data->SyncTransCurState = TRUE;
  292. } else {
  293. data->SyncTransOrigState = FALSE;
  294. data->SyncTransCurState = FALSE;
  295. }
  296. return ERROR_SUCCESS;
  297. }
  298. BOOL
  299. ScsiOnInitDialog(HWND HWnd,
  300. HWND HWndFocus,
  301. LPARAM LParam)
  302. {
  303. LPPROPSHEETPAGE page = (LPPROPSHEETPAGE) LParam;
  304. PSCSI_PAGE_DATA scsiData = (PSCSI_PAGE_DATA) page->lParam;
  305. //
  306. // Set the states of the checkboxes
  307. //
  308. if (ERROR_SUCCESS == GetDefaultRequestFlags(scsiData)) {
  309. CheckDlgButton(HWnd,
  310. IDC_SCSI_SYNCHONOUS_TX,
  311. scsiData->SyncTransOrigState);
  312. }
  313. if (ERROR_SUCCESS == GetRequestFlagsMask(scsiData)) {
  314. CheckDlgButton(HWnd,
  315. IDC_SCSI_TAGGED_QUEUING,
  316. scsiData->TagQueuingOrigState);
  317. }
  318. SetWindowLongPtr(HWnd, DWLP_USER, (LONG_PTR) scsiData);
  319. return TRUE;
  320. }
  321. LRESULT
  322. ScsiOnNotify (HWND HWnd,
  323. int HWndFocus,
  324. LPNMHDR lpNMHdr)
  325. {
  326. PSCSI_PAGE_DATA scsiData = (PSCSI_PAGE_DATA) GetWindowLongPtr(HWnd,
  327. DWLP_USER);
  328. switch(lpNMHdr->code) {
  329. case PSN_APPLY: {
  330. SetRequestFlagsMask(scsiData);
  331. SetDefaultRequestFlags(scsiData);
  332. break;
  333. }
  334. }
  335. return 0;
  336. }
  337. VOID
  338. ScsiOnCommand(HWND HWnd,
  339. int id,
  340. HWND HWndCtl,
  341. UINT codeNotify)
  342. {
  343. PSCSI_PAGE_DATA scsiData = (PSCSI_PAGE_DATA) GetWindowLongPtr(HWnd,
  344. DWLP_USER);
  345. TCHAR buf[MAX_PATH];
  346. switch (id) {
  347. case IDC_SCSI_TAGGED_QUEUING:
  348. scsiData->TagQueuingCurState = !scsiData->TagQueuingCurState;
  349. if(scsiData->TagQueuingCurState != scsiData->TagQueuingOrigState) {
  350. PropSheet_Changed(GetParent(HWnd), HWnd);
  351. }
  352. break;
  353. case IDC_SCSI_SYNCHONOUS_TX:
  354. scsiData->SyncTransCurState = !scsiData->SyncTransCurState;
  355. if(scsiData->SyncTransCurState != scsiData->SyncTransOrigState) {
  356. PropSheet_Changed(GetParent(HWnd), HWnd);
  357. }
  358. break;
  359. }
  360. }
  361. INT_PTR
  362. ScsiDialogProc(
  363. HWND Dialog,
  364. UINT Message,
  365. WPARAM wParam,
  366. LPARAM lParam
  367. )
  368. {
  369. switch(Message) {
  370. HANDLE_MSG(Dialog, WM_INITDIALOG, ScsiOnInitDialog);
  371. HANDLE_MSG(Dialog, WM_COMMAND, ScsiOnCommand);
  372. HANDLE_MSG(Dialog, WM_NOTIFY, ScsiOnNotify);
  373. case WM_CONTEXTMENU:
  374. return ScsiContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  375. case WM_HELP:
  376. ScsiHelp(Dialog, (LPHELPINFO) lParam);
  377. break;
  378. default: {
  379. return FALSE;
  380. break;
  381. }
  382. }
  383. return TRUE;
  384. }
  385. BOOL
  386. ScsiDialogCallback(
  387. HWND Dialog,
  388. UINT Message,
  389. LPPROPSHEETPAGE Page
  390. )
  391. {
  392. return TRUE;
  393. }
  394. BOOL
  395. ScsiCheckDriveType (
  396. IN HDEVINFO DeviceInfoSet,
  397. IN PSP_DEVINFO_DATA DeviceInfoData)
  398. {
  399. HKEY hDeviceKey;
  400. TCHAR * szHwIds = NULL;
  401. DWORD i;
  402. for (i=1;i<=4;i++) {
  403. szHwIds = LocalAlloc(LPTR, i*512);
  404. if (szHwIds == NULL) {
  405. return FALSE;
  406. }
  407. if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
  408. DeviceInfoData,
  409. SPDRP_HARDWAREID,
  410. NULL,
  411. (PBYTE) szHwIds,
  412. i*512,
  413. NULL)) {
  414. if ( _tcsncmp(TEXT("SCSI"), szHwIds, 4) == 0 ) {
  415. LocalFree(szHwIds);
  416. return TRUE;
  417. }
  418. LocalFree(szHwIds);
  419. return FALSE;
  420. }
  421. LocalFree(szHwIds);
  422. //
  423. // ISSUE-2000/5/24-henrygab - need to loop when buffer is too small only
  424. //
  425. #if 0
  426. if (GetLastError() != ERROR_BUFFER_TOO_SMALL) {
  427. return FALSE;
  428. }
  429. #endif // FALSE
  430. }
  431. return FALSE;
  432. }