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.

616 lines
21 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: ppa3x.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. VOID
  12. ParCheckEnableLegacyZipFlag()
  13. /*++
  14. Routine Description:
  15. Initialize debugging variables from registry; set to default values
  16. if anything fails.
  17. Arguments:
  18. RegistryPath - Root path in registry where we should look
  19. Return Value:
  20. None
  21. --*/
  22. {
  23. NTSTATUS Status;
  24. RTL_QUERY_REGISTRY_TABLE paramTable[2];
  25. ULONG defaultZipEnabled = 0;
  26. PWSTR suffix = L"\\Parameters";
  27. UNICODE_STRING path = {0,0,0};
  28. ULONG length;
  29. //
  30. // set up table entries for call to RtlQueryRegistryValues
  31. //
  32. RtlZeroMemory( paramTable, sizeof(paramTable));
  33. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  34. paramTable[0].Name = (PWSTR)L"ParEnableLegacyZip";
  35. paramTable[0].EntryContext = &ParEnableLegacyZip;
  36. paramTable[0].DefaultType = REG_DWORD;
  37. paramTable[0].DefaultData = &defaultZipEnabled;
  38. paramTable[0].DefaultLength = sizeof(ULONG);
  39. //
  40. // leave paramTable[2] as all zeros - this terminates the table
  41. //
  42. Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
  43. RegistryPath.Buffer,
  44. &paramTable[0],
  45. NULL,
  46. NULL);
  47. ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - status from RtlQueryRegistryValues = %x\n", Status) );
  48. if( !NT_SUCCESS( Status ) ) {
  49. // registry read failed, use defaults
  50. ParEnableLegacyZip = defaultZipEnabled;
  51. return;
  52. }
  53. if( ParEnableLegacyZip ) {
  54. // we found a non-zero value - enable PnP for old parallel port Zip
  55. ParDump2(PARPNP1, ("ppa3x::ParCheckEnableLegacyZipFlag - FOUND - ParEnableLegacyZip Flag = %08x\n", ParEnableLegacyZip) );
  56. return;
  57. }
  58. //
  59. // We didn't find the registry flag, maybe it's under the Parameters subkey
  60. //
  61. // compute the size of the path including the "parameters" suffix
  62. ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - RegPath length = %d\n", RegistryPath.Length) );
  63. length = ( sizeof(WCHAR) * wcslen( suffix ) ) + sizeof(UNICODE_NULL);
  64. ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - suffix length = %d\n", length) );
  65. length += RegistryPath.Length;
  66. ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - total dest length = %d\n", length) );
  67. // build the path
  68. path.Buffer = ExAllocatePool( PagedPool, length );
  69. if( NULL == path.Buffer ) {
  70. // out of pool, use defaults
  71. ParEnableLegacyZip = defaultZipEnabled;
  72. return;
  73. }
  74. RtlZeroMemory( path.Buffer, length );
  75. path.MaximumLength = (USHORT)length;
  76. RtlCopyUnicodeString( &path, &RegistryPath );
  77. RtlAppendUnicodeToString( &path, suffix );
  78. ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - path = <%wZ>\n", &path) );
  79. // query at new location in registry
  80. Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
  81. path.Buffer,
  82. &paramTable[0],
  83. NULL,
  84. NULL);
  85. RtlFreeUnicodeString( &path );
  86. ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - status from RtlQueryRegistryValues on SubKey = %x\n", Status) );
  87. if( !NT_SUCCESS( Status ) ) {
  88. // registry read failed, use defaults
  89. ParEnableLegacyZip = defaultZipEnabled;
  90. return;
  91. }
  92. ParDump2(PARPNP1, ("ppa3x::ParCheckEnableLegacyZipFlag - FOUND SubKey ParEnableLegacyZip Flag = %08x\n", ParEnableLegacyZip) );
  93. }
  94. BOOLEAN
  95. ParLegacyZipCheckDevice(
  96. PUCHAR Controller
  97. )
  98. {
  99. WRITE_PORT_UCHAR( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_AUTOFEED) );
  100. if ( (READ_PORT_UCHAR( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) == DSR_NOT_FAULT ) {
  101. WRITE_PORT_UCHAR( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
  102. if ( (READ_PORT_UCHAR( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) != DSR_NOT_FAULT ) {
  103. // A device was found
  104. return TRUE;
  105. }
  106. }
  107. // No device is there
  108. return FALSE;
  109. } // end PptLegacyZipCheckDevice()
  110. PCHAR ParBuildLegacyZipDeviceId()
  111. {
  112. ULONG size = sizeof(PAR_LGZIP_PSEUDO_1284_ID_STRING) + sizeof(NULL);
  113. PCHAR id = ExAllocatePool(PagedPool, size);
  114. if( id ) {
  115. RtlZeroMemory( id, size );
  116. RtlCopyMemory( id, ParLegacyZipPseudoId, size - sizeof(NULL) );
  117. return id;
  118. } else {
  119. return NULL;
  120. }
  121. }
  122. PCHAR
  123. Par3QueryLegacyZipDeviceId(
  124. IN PDEVICE_EXTENSION Extension,
  125. OUT PCHAR CallerDeviceIdBuffer, OPTIONAL
  126. IN ULONG CallerBufferSize,
  127. OUT PULONG DeviceIdSize,
  128. IN BOOLEAN bReturnRawString // TRUE == include the 2 size bytes in the returned string
  129. // FALSE == discard the 2 size bytes
  130. )
  131. {
  132. USHORT deviceIdSize;
  133. PCHAR deviceIdBuffer;
  134. UNREFERENCED_PARAMETER( Extension );
  135. // initialize returned size in case we have an error
  136. *DeviceIdSize = 0;
  137. deviceIdBuffer = ParBuildLegacyZipDeviceId();
  138. if( !deviceIdBuffer ) {
  139. // error, likely out of resources
  140. return NULL;
  141. }
  142. deviceIdSize = (USHORT) strlen(deviceIdBuffer);
  143. *DeviceIdSize = deviceIdSize;
  144. if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
  145. // caller supplied buffer is large enough, use it
  146. RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
  147. RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
  148. ExFreePool( deviceIdBuffer );
  149. return CallerDeviceIdBuffer;
  150. } else {
  151. // caller buffer too small, return pointer to our buffer
  152. return deviceIdBuffer;
  153. }
  154. }
  155. PDEVICE_OBJECT
  156. ParCreateLegacyZipPdo(
  157. IN PDEVICE_OBJECT LegacyPodo,
  158. UCHAR Dot3Id
  159. )
  160. /*++
  161. Routine Description:
  162. Create PDO for legacy Zip Drive
  163. LegacyPodo - points to the Legacy PODO for the port
  164. Return Value:
  165. PDEVICE_OBJECT - on success, points to the PDO we create
  166. NULL - otherwise
  167. --*/
  168. {
  169. PDEVICE_EXTENSION legacyExt = LegacyPodo->DeviceExtension;
  170. PDRIVER_OBJECT driverObject = LegacyPodo->DriverObject;
  171. PDEVICE_OBJECT fdo = legacyExt->ParClassFdo;
  172. UNICODE_STRING className = {0,0,NULL};
  173. NTSTATUS status;
  174. PCHAR deviceIdString = NULL;
  175. ULONG deviceIdLength = 0;
  176. PDEVICE_OBJECT newDevObj = NULL;
  177. PDEVICE_EXTENSION newDevExt;
  178. ULONG idTry = 1;
  179. ULONG maxIdTries = 3;
  180. BOOLEAN useModifiedClassName = FALSE;
  181. UNICODE_STRING modifiedClassName;
  182. UNICODE_STRING suffix;
  183. UNICODE_STRING dash;
  184. WCHAR suffixBuffer[10];
  185. ULONG number = 0;
  186. ULONG maxNumber = 256;
  187. ULONG newLength;
  188. PAGED_CODE();
  189. //
  190. // Query for PnP device
  191. //
  192. while( (NULL == deviceIdString) && (idTry <= maxIdTries) ) {
  193. if( Dot3Id == DOT3_LEGACY_ZIP_ID) {
  194. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - calling ParBuildLegacyZipDeviceId()\n"));
  195. deviceIdString = ParBuildLegacyZipDeviceId();
  196. if(deviceIdString)
  197. {
  198. deviceIdLength = strlen( deviceIdString );
  199. }
  200. } else{
  201. ASSERT(FALSE); // should never get here
  202. deviceIdString = Par3QueryDeviceId(legacyExt, NULL, 0, &deviceIdLength, FALSE, FALSE);
  203. }
  204. if( NULL == deviceIdString ) {
  205. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - no 1284 ID on try %d\n", idTry) );
  206. KeStallExecutionProcessor(1);
  207. ++idTry;
  208. } else {
  209. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - devIdString=<%s> on try %d\n", deviceIdString, idTry) );
  210. }
  211. }
  212. if( !deviceIdString ) {
  213. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - no 1284 ID, bail out\n") );
  214. return NULL;
  215. }
  216. //
  217. // Found PnP Device, create a PDO to represent the device
  218. // - create classname
  219. // - create device object
  220. // - initialize device object and extension
  221. // - create symbolic link
  222. // - register for PnP TargetDeviceChange notification
  223. //
  224. //
  225. // Create a class name of the form \Device\ParallelN,
  226. //
  227. ParMakeDotClassNameFromBaseClassName(&legacyExt->ClassName, Dot3Id, &className);
  228. if( !className.Buffer ) {
  229. // unable to construct ClassName
  230. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - unable to construct ClassName for device\n") );
  231. ExFreePool(deviceIdString);
  232. return NULL;
  233. }
  234. //
  235. // create device object
  236. //
  237. status = ParCreateDevice(driverObject, sizeof(DEVICE_EXTENSION), &className,
  238. FILE_DEVICE_PARALLEL_PORT, 0, TRUE, &newDevObj);
  239. ///
  240. if( status == STATUS_OBJECT_NAME_COLLISION ) {
  241. //
  242. // old name is still in use, appending a suffix and try again
  243. //
  244. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ParCreateDevice FAILED due to name Collision on <%wZ> - retry\n", &className));
  245. useModifiedClassName = TRUE;
  246. suffix.Length = 0;
  247. suffix.MaximumLength = sizeof(suffixBuffer);
  248. suffix.Buffer = suffixBuffer;
  249. RtlInitUnicodeString( &dash, (PWSTR)L"-" );
  250. newLength = className.MaximumLength + 5*sizeof(WCHAR); // L"-XXX" suffix
  251. modifiedClassName.Length = 0;
  252. modifiedClassName.MaximumLength = (USHORT)newLength;
  253. modifiedClassName.Buffer = ExAllocatePool(PagedPool, newLength);
  254. if( NULL == modifiedClassName.Buffer ) {
  255. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ParCreateDevice FAILED - no PagedPool avail\n"));
  256. ExFreePool(deviceIdString);
  257. RtlFreeUnicodeString( &className );
  258. return NULL;
  259. }
  260. while( ( status == STATUS_OBJECT_NAME_COLLISION ) && ( number <= maxNumber ) ) {
  261. status = RtlIntegerToUnicodeString(number, 10, &suffix);
  262. if ( !NT_SUCCESS(status) ) {
  263. ExFreePool(deviceIdString);
  264. RtlFreeUnicodeString( &className );
  265. RtlFreeUnicodeString( &modifiedClassName );
  266. return NULL;
  267. }
  268. RtlCopyUnicodeString( &modifiedClassName, &className );
  269. RtlAppendUnicodeStringToString( &modifiedClassName, &dash );
  270. RtlAppendUnicodeStringToString( &modifiedClassName, &suffix );
  271. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - trying ParCreateDevice with className <%wZ>\n", &modifiedClassName));
  272. status = ParCreateDevice(driverObject, sizeof(DEVICE_EXTENSION), &modifiedClassName,
  273. FILE_DEVICE_PARALLEL_PORT, 0, TRUE, &newDevObj);
  274. if( NT_SUCCESS( status ) ) {
  275. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ParCreateDevice returned SUCCESS with className <%wZ>\n", &modifiedClassName));
  276. } else {
  277. ++number;
  278. }
  279. }
  280. }
  281. ///
  282. if( useModifiedClassName ) {
  283. // copy modifiedClassName to className
  284. RtlFreeUnicodeString( &className );
  285. className = modifiedClassName;
  286. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - copy useModifiedClassName to className - className=<%wZ>\n", &className));
  287. }
  288. if( !NT_SUCCESS(status) ) {
  289. // unable to create device object, bail out
  290. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - unable to create device object "
  291. "className=<%wZ>, bail out - status=%x\n", &className, status) );
  292. ExFreePool(deviceIdString);
  293. RtlFreeUnicodeString(&className);
  294. ParLogError(fdo->DriverObject, NULL, PhysicalZero, PhysicalZero,
  295. 0, 0, 0, 9, STATUS_SUCCESS, PAR_INSUFFICIENT_RESOURCES);
  296. return NULL;
  297. } else {
  298. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - device created <%wZ>\n", &className));
  299. }
  300. //
  301. // device object created
  302. //
  303. newDevExt = newDevObj->DeviceExtension;
  304. //
  305. // initialize device object and extension
  306. //
  307. ParInitCommonDOPre(newDevObj, fdo, &className);
  308. status = ParInitPdo(newDevObj, (PUCHAR)deviceIdString, deviceIdLength, LegacyPodo, Dot3Id);
  309. if( !NT_SUCCESS( status ) ) {
  310. // initialization failed, clean up and bail out
  311. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - call to ParInitPdo failed, bail out\n") );
  312. ParAcquireListMutexAndKillDeviceObject(fdo, newDevObj);
  313. return NULL;
  314. }
  315. ParInitCommonDOPost(newDevObj);
  316. //
  317. // create symbolic link
  318. //
  319. if( newDevExt->SymbolicLinkName.Buffer ) {
  320. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ready to create symlink - SymbolicLinkName <%wZ>, ClassName <%wZ>\n",
  321. &newDevExt->SymbolicLinkName, &newDevExt->ClassName) );
  322. ParDump2(PARPNP1, (" - Length=%hd, MaximumLength=%hd\n", newDevExt->ClassName.Length, newDevExt->ClassName.MaximumLength) );
  323. ASSERT(newDevExt->ClassName.Length < 100);
  324. PAGED_CODE();
  325. status = IoCreateUnprotectedSymbolicLink(&newDevExt->SymbolicLinkName, &newDevExt->ClassName);
  326. if ( NT_SUCCESS(status) ) {
  327. // note this in our extension for later cleanup
  328. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - SymbolicLinkName -> ClassName = <%wZ> -> <%wZ>\n",
  329. &newDevExt->SymbolicLinkName, &newDevExt->ClassName) );
  330. newDevExt->CreatedSymbolicLink = TRUE;
  331. // Write symbolic link map info to the registry.
  332. status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
  333. (PWSTR)L"PARALLEL PORTS",
  334. newDevExt->ClassName.Buffer,
  335. REG_SZ,
  336. newDevExt->SymbolicLinkName.Buffer,
  337. newDevExt->SymbolicLinkName.Length +
  338. sizeof(WCHAR));
  339. if (!NT_SUCCESS(status)) {
  340. // unable to write map info to registry - continue anyway
  341. ParLogError(newDevObj->DriverObject, newDevObj,
  342. newDevExt->OriginalController, PhysicalZero,
  343. 0, 0, 0, 6, status, PAR_NO_DEVICE_MAP_CREATED);
  344. }
  345. } else {
  346. // unable to create the symbolic link.
  347. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - unable to create SymbolicLink - status = %x\n",status));
  348. newDevExt->CreatedSymbolicLink = FALSE;
  349. RtlFreeUnicodeString(&newDevExt->SymbolicLinkName);
  350. ParLogError(newDevObj->DriverObject, newDevObj,
  351. newDevExt->OriginalController, PhysicalZero,
  352. 0, 0, 0, 5, status, PAR_NO_SYMLINK_CREATED);
  353. }
  354. } else {
  355. // extension does not contain a symbolic link name for us to use
  356. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - extension does not contain a symbolic link for us to use\n"));
  357. newDevExt->CreatedSymbolicLink = FALSE;
  358. }
  359. // End-Of-Chain PDO - register for PnP TargetDeviceChange notification
  360. status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange,
  361. 0,
  362. (PVOID)newDevExt->PortDeviceFileObject,
  363. driverObject,
  364. (PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) ParPnpNotifyTargetDeviceChange,
  365. (PVOID)newDevObj,
  366. &newDevExt->NotificationHandle);
  367. if( !NT_SUCCESS(status) ) {
  368. // PnP registration for TargetDeviceChange notification failed,
  369. // clean up and bail out
  370. ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - PnP registration failed, killing PDO\n") );
  371. ParAcquireListMutexAndKillDeviceObject(fdo, newDevObj);
  372. return NULL;
  373. }
  374. return newDevObj;
  375. }
  376. PDEVICE_OBJECT
  377. ParCreateAddLegacyZipPdo(
  378. IN PDEVICE_OBJECT LegacyPodo
  379. )
  380. /*++
  381. Create a new PDO for the legacy Zip and add the PDO to the list
  382. of PDOs
  383. --*/
  384. {
  385. PDEVICE_OBJECT newPdo = ParCreateLegacyZipPdo( LegacyPodo, DOT3_LEGACY_ZIP_ID );
  386. if( newPdo ) {
  387. ParAddDevObjToFdoList( newPdo );
  388. }
  389. return newPdo;
  390. }
  391. NTSTATUS
  392. ParSelectLegacyZip( IN PDEVICE_OBJECT PortDeviceObject )
  393. //
  394. // Select Legacy Zip Drive
  395. //
  396. // Note: Caller must have already Acquired the Port prior to calling this function.
  397. //
  398. // Returns: STATUS_SUCCESS if drive selected, !STATUS_SUCCESS otherwise
  399. //
  400. {
  401. PARALLEL_1284_COMMAND par1284Command;
  402. NTSTATUS status;
  403. ParDump2(PARLGZIP, ("rescan::ParSelectLegacyZip - Enter\n"));
  404. par1284Command.ID = 0;
  405. par1284Command.Port = 0;
  406. par1284Command.CommandFlags = PAR_HAVE_PORT_KEEP_PORT | PAR_LEGACY_ZIP_DRIVE;
  407. status = ParBuildSendInternalIoctl(IOCTL_INTERNAL_SELECT_DEVICE,
  408. PortDeviceObject,
  409. &par1284Command, sizeof(PARALLEL_1284_COMMAND),
  410. NULL, 0, NULL);
  411. ParDump2(PARLGZIP, ("rescan::ParSelectLegacyZip - returning status = %x\n", status));
  412. return status;
  413. }
  414. NTSTATUS
  415. ParDeselectLegacyZip( IN PDEVICE_OBJECT PortDeviceObject )
  416. //
  417. // Select Legacy Zip Drive
  418. //
  419. // Note: This function does not Release the port so the Caller still has
  420. // the port after this function returns.
  421. //
  422. // Returns: STATUS_SUCCESS if drive deselected, !STATUS_SUCCESS otherwise
  423. // (we don't expect this call to ever fail, but check just
  424. // in case)
  425. //
  426. {
  427. PARALLEL_1284_COMMAND par1284Command;
  428. NTSTATUS status;
  429. ParDump2(PARLGZIP, ("rescan::ParDeselectLegacyZip - Enter\n"));
  430. par1284Command.ID = 0;
  431. par1284Command.Port = 0;
  432. par1284Command.CommandFlags = PAR_HAVE_PORT_KEEP_PORT | PAR_LEGACY_ZIP_DRIVE;
  433. status = ParBuildSendInternalIoctl(IOCTL_INTERNAL_DESELECT_DEVICE,
  434. PortDeviceObject,
  435. &par1284Command, sizeof(PARALLEL_1284_COMMAND),
  436. NULL, 0, NULL);
  437. ParDump2(PARLGZIP, ("rescan::ParDeselectLegacyZip - returning status = %x\n", status));
  438. return status;
  439. }
  440. BOOLEAN
  441. ParZipPresent( PDEVICE_OBJECT LegacyPodo )
  442. //
  443. // Legacy Zip is present if we can SELECT it
  444. //
  445. {
  446. BOOLEAN zipPresent = FALSE;
  447. PDEVICE_EXTENSION legacyExt = LegacyPodo->DeviceExtension;
  448. PDEVICE_OBJECT portDeviceObject = legacyExt->PortDeviceObject;
  449. if( NT_SUCCESS( ParSelectLegacyZip( portDeviceObject ) ) ) {
  450. ParDeselectLegacyZip( portDeviceObject );
  451. zipPresent = TRUE;
  452. }
  453. return zipPresent;
  454. }
  455. VOID
  456. ParRescanLegacyZip( IN PPAR_DEVOBJ_STRUCT CurrentNode )
  457. //
  458. // Rescan for change in Legacy Zip Drive, update PDO list if change detected
  459. //
  460. {
  461. BOOLEAN hadZip;
  462. BOOLEAN foundZip;
  463. PDEVICE_OBJECT zipPdo;
  464. ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - Enter\n"));
  465. if( !ParEnableLegacyZip ) {
  466. //
  467. // legacy zip detection is disabled
  468. //
  469. ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - !ParEnableLegacyZip\n"));
  470. //
  471. // if we had a Legacy Zip then automatically mark it as hardware gone
  472. //
  473. zipPdo = CurrentNode->LegacyZipPdo;
  474. if( zipPdo ) {
  475. // we should never get here, but handle it if we do
  476. ParMarkPdoHardwareGone( zipPdo->DeviceExtension );
  477. }
  478. return;
  479. }
  480. //
  481. // Check for presence of Legacy Zip - update PDO list if we detect a change
  482. //
  483. hadZip = (NULL != CurrentNode->LegacyZipPdo);
  484. foundZip = ParZipPresent( CurrentNode->LegacyPodo );
  485. ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - hadZip=%s, foundZip=%s\n",
  486. hadZip?"TRUE":"FALSE", foundZip?"TRUE":"FALSE"));
  487. if( foundZip && !hadZip ) {
  488. // we found a new Zip - create a PDO for it
  489. ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - Found new Legacy Zip\n"));
  490. ParCreateAddLegacyZipPdo( CurrentNode->LegacyPodo );
  491. } else if( !foundZip && hadZip ) {
  492. // our Zip went away - mark PDO as hardware gone
  493. ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - Had a Legacy Zip but now it's gone\n"));
  494. zipPdo = CurrentNode->LegacyZipPdo;
  495. ParMarkPdoHardwareGone( zipPdo->DeviceExtension );
  496. }
  497. return;
  498. }