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.

8029 lines
280 KiB

  1. /*
  2. Copyright (c) 1997 M-Systems
  3. Module Name:
  4. tffsport.c
  5. Author:
  6. Alexander Geller
  7. Environment:
  8. Kernel mode
  9. --*/
  10. #include "ntddk.h"
  11. #include "scsi.h"
  12. #include "ntdddisk.h"
  13. #include "ntddscsi.h"
  14. #include "string.h"
  15. #include "stdio.h"
  16. #include "stdarg.h"
  17. #include "ntddstor.h"
  18. #include "initguid.h"
  19. #include "ntddscsi.h"
  20. #include "blockdev.h"
  21. #include "nfdc2148.h"
  22. //#include "mdocplus.h"
  23. #include "tffsport.h"
  24. #include "ntioctl.h"
  25. #define TFFSPORT_POOL_TAG 'dffT' // - Tffd Tffsport Driver Tag
  26. KTIMER timerObject;
  27. KDPC timerDpc;
  28. BOOLEAN timerWasStarted = FALSE;
  29. BOOLEAN patitionTwo = FALSE;
  30. /* Private GUID for WMI */
  31. DEFINE_GUID(WmiTffsportAddressGuid,
  32. 0xd9a8f150,
  33. 0xf830,
  34. 0x11d2,
  35. 0xb5, 0x72, 0x00, 0xc0, 0x4f, 0x65, 0xb3, 0xd9
  36. );
  37. TempINFO info[VOLUMES];
  38. ULONG TrueffsNextDeviceNumber_tffsport = 0;
  39. CRASHDUMP_DATA DumpData;
  40. extern NTsocketParams driveInfo[SOCKETS];
  41. ULONG VerifyWriteState[SOCKETS];
  42. FAST_MUTEX driveInfoReferenceMutex;
  43. const TFFS_DEVICE_TYPE TffsDeviceType_tffsport[] = {
  44. {"Disk", "GenDisk", "DiskPeripheral"}
  45. };
  46. const TFFS_DEVICE_TYPE TffsDeviceTypeFDO_tffsport[] = {
  47. {"Controller", "FlashDiskController", "FlashDiskPeripheral"}
  48. };
  49. BOOLEAN
  50. DebugLogEvent(IN PDRIVER_OBJECT DriverObject, IN ULONG Value);
  51. NTSTATUS
  52. TrueffsStartDeviceOnDetect(IN PDEVICE_EXTENSION deviceExtension, IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN CheckResources);
  53. #ifdef ALLOC_PRAGMA
  54. #pragma alloc_text(INIT, DriverEntry)
  55. #pragma alloc_text(PAGE, TrueffsThread)
  56. #endif
  57. NTSTATUS
  58. DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  59. /*++
  60. Routine Description:
  61. This routine is called at system initialization time so we can fill in the basic dispatch points
  62. Arguments:
  63. DriverObject - Supplies the driver object.
  64. RegistryPath - Supplies the registry path for this driver.
  65. Return Value:
  66. STATUS_SUCCESS
  67. --*/
  68. {
  69. PTRUEFFSDRIVER_EXTENSION trueffsDriverExtension;
  70. NTSTATUS status;
  71. ULONG i;
  72. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DriverEntry\n"));
  73. DebugLogEvent(DriverObject, 1);
  74. DebugLogEvent(DriverObject, 2);
  75. DebugLogEvent(DriverObject, 3);
  76. for (i = 0; i < SOCKETS; i++) {
  77. driveInfo[i].interfAlive = 0;
  78. driveInfo[i].fdoExtension = NULL;
  79. }
  80. for (i = 0; i < VOLUMES; i++) {
  81. info[i].baseAddress= 0;
  82. info[i].nextPartition= 0;
  83. }
  84. ExInitializeFastMutex(&driveInfoReferenceMutex);
  85. if (!DriverObject) {
  86. return TrueffsCrashDumpDriverEntry(RegistryPath);
  87. }
  88. // Allocate Driver Object Extension for storing the RegistryPath
  89. status = IoAllocateDriverObjectExtension(
  90. DriverObject,
  91. DRIVER_OBJECT_EXTENSION_ID,
  92. sizeof (DRIVER_EXTENSION),
  93. &trueffsDriverExtension
  94. );
  95. if (!NT_SUCCESS(status)) {
  96. TffsDebugPrint ((TFFS_DEB_ERROR,"Trueffs: DriverEntry: Unable to create driver extension\n"));
  97. return status;
  98. }
  99. RtlZeroMemory (
  100. trueffsDriverExtension,
  101. sizeof (DRIVER_EXTENSION)
  102. );
  103. // make copy of the RegistryPath
  104. trueffsDriverExtension->RegistryPath.Buffer = ExAllocatePoolWithTag (NonPagedPool, RegistryPath->Length * sizeof(WCHAR), TFFSPORT_POOL_TAG);
  105. if (trueffsDriverExtension->RegistryPath.Buffer == NULL) {
  106. TffsDebugPrint ((TFFS_DEB_ERROR,"Trueffs: DriverEntry: Unable to allocate memory for registry path\n"));
  107. return STATUS_INSUFFICIENT_RESOURCES;
  108. }
  109. trueffsDriverExtension->RegistryPath.Length = 0;
  110. trueffsDriverExtension->RegistryPath.MaximumLength = RegistryPath->Length;
  111. RtlCopyUnicodeString (&trueffsDriverExtension->RegistryPath, RegistryPath);
  112. // Initialize the Driver Object with driver's entry points
  113. DriverObject->MajorFunction[IRP_MJ_CREATE] = TrueffsCreateClose;
  114. DriverObject->MajorFunction[IRP_MJ_CLOSE] = TrueffsCreateClose;
  115. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TrueffsDeviceControl;
  116. DriverObject->MajorFunction[IRP_MJ_SCSI] = TrueffsScsiRequests;
  117. DriverObject->DriverExtension->AddDevice = TrueffsAddDevice;
  118. DriverObject->MajorFunction[IRP_MJ_PNP] = TrueffsPnpDeviceControl;
  119. DriverObject->MajorFunction[IRP_MJ_POWER] = TrueffsPowerControl;
  120. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = TrueffsDispatchSystemControl;
  121. DriverObject->DriverStartIo = TrueffsStartIo;
  122. DriverObject->DriverUnload = TrueffsUnload;
  123. TrueffsWmiInit();
  124. TrueffsDetectDiskOnChip(DriverObject, RegistryPath);
  125. return STATUS_SUCCESS;
  126. }
  127. NTSTATUS
  128. TrueffsFetchKeyValue(
  129. IN PDRIVER_OBJECT DriverObject,
  130. IN PUNICODE_STRING RegistryPath,
  131. IN PWSTR KeyName,
  132. IN OUT ULONG* KeyValue
  133. )
  134. {
  135. RTL_QUERY_REGISTRY_TABLE Table[3]; //must be parmaters + 2
  136. UNICODE_STRING SubPath;
  137. WCHAR PathNameBuffer[30];
  138. NTSTATUS ntStatus;
  139. //TffsDebugPrint(("Trueffs: TrueffsFetchKeyValue Start\n"));
  140. // Prepare Table - Must be Zero Terminated
  141. RtlZeroMemory(Table, sizeof(Table));
  142. // Create name string for the query Table
  143. SubPath.Buffer = PathNameBuffer;
  144. SubPath.MaximumLength = sizeof(PathNameBuffer);
  145. SubPath.Length = 0;
  146. RtlAppendUnicodeToString(&SubPath,L"Parameters");
  147. // 0 - just move us to the correct place under "Parameters" subkey
  148. Table[0].Name = SubPath.Buffer;
  149. Table[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
  150. Table[1].Name = KeyName;
  151. Table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  152. Table[1].EntryContext = KeyValue;
  153. *KeyValue = -1;
  154. ntStatus = RtlQueryRegistryValues(
  155. RTL_REGISTRY_ABSOLUTE,
  156. RegistryPath->Buffer,
  157. Table,
  158. NULL,NULL);
  159. if ( ((*KeyValue)==-1) || (!NT_SUCCESS(ntStatus)) )
  160. {
  161. //TffsDebugPrint(("Trueffs: TrueffsFetchKeyValue End, Key Not Found\n"));
  162. return STATUS_OBJECT_NAME_NOT_FOUND;
  163. }
  164. else
  165. {
  166. //TffsDebugPrint(("Trueffs: TrueffsFetchKeyValue End, Key Found\n"));
  167. return ntStatus;
  168. }
  169. }
  170. NTSTATUS
  171. TrueffsDetectRegistryValues(
  172. IN PDRIVER_OBJECT DriverObject,
  173. IN PUNICODE_STRING RegistryPath
  174. )
  175. {
  176. RTL_QUERY_REGISTRY_TABLE Table[14]; //must be parmaters + 2
  177. NTSTATUS ntStatus;
  178. ULONG prevValue;
  179. ULONG keyValue;
  180. FLStatus status = flOK;
  181. ULONG CurrVerifyWriteState;
  182. ULONG currSocket = 0;
  183. //TffsDebugPrint(("Trueffs: TrueffsDetectRegistryValues Start\n"));
  184. #ifdef ENVIRONMENT_VARS
  185. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_ISRAM_CHECK_ENABLED",&keyValue);
  186. if (NT_SUCCESS(ntStatus))
  187. status = flSetEnvAll(FL_IS_RAM_CHECK_ENABLED,keyValue,&prevValue);
  188. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_TL_CACHE_ENABLED",&keyValue);
  189. if (NT_SUCCESS(ntStatus))
  190. status = flSetEnvAll(FL_TL_CACHE_ENABLED,keyValue,&prevValue);
  191. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_DOC_8BIT_ACCESS",&keyValue);
  192. if (NT_SUCCESS(ntStatus))
  193. status = flSetEnvAll(FL_DOC_8BIT_ACCESS,keyValue,&prevValue);
  194. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_SUSPEND_MODE",&keyValue);
  195. if (NT_SUCCESS(ntStatus))
  196. status = flSetEnvAll(FL_SUSPEND_MODE,keyValue,&prevValue);
  197. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_MTD_BUS_ACCESS_TYPE",&keyValue);
  198. if (NT_SUCCESS(ntStatus))
  199. status = flSetEnvAll(FL_MTD_BUS_ACCESS_TYPE,keyValue,&prevValue);
  200. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_SET_POLICY",&keyValue);
  201. if (NT_SUCCESS(ntStatus))
  202. status = flSetEnvAll(FL_SET_POLICY,keyValue,&prevValue);
  203. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL0",&CurrVerifyWriteState);
  204. if (NT_SUCCESS(ntStatus) && currSocket++<SOCKETS)
  205. VerifyWriteState[0] = CurrVerifyWriteState;
  206. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL1",&CurrVerifyWriteState);
  207. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  208. VerifyWriteState[1] = CurrVerifyWriteState;
  209. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL2",&CurrVerifyWriteState);
  210. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  211. VerifyWriteState[2] = CurrVerifyWriteState;
  212. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL3",&CurrVerifyWriteState);
  213. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  214. VerifyWriteState[3] = CurrVerifyWriteState;
  215. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL4",&CurrVerifyWriteState);
  216. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  217. VerifyWriteState[4] = CurrVerifyWriteState;
  218. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL5",&CurrVerifyWriteState);
  219. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  220. VerifyWriteState[5] = CurrVerifyWriteState;
  221. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL6",&CurrVerifyWriteState);
  222. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  223. VerifyWriteState[6] = CurrVerifyWriteState;
  224. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BDTL7",&CurrVerifyWriteState);
  225. if (NT_SUCCESS(ntStatus)&& currSocket++<SOCKETS)
  226. VerifyWriteState[7] = CurrVerifyWriteState;
  227. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_SECTORS_VERIFIED_PER_FOLDING",&keyValue);
  228. if (NT_SUCCESS(ntStatus))
  229. status = flSetEnvAll(FL_SECTORS_VERIFIED_PER_FOLDING,keyValue,&prevValue);
  230. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_BINARY",&keyValue);
  231. if (NT_SUCCESS(ntStatus))
  232. status = flSetEnvAll(FL_VERIFY_WRITE_BINARY,keyValue,&prevValue);
  233. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_VERIFY_WRITE_OTHER",&keyValue);
  234. if (NT_SUCCESS(ntStatus))
  235. status = flSetEnvAll(FL_VERIFY_WRITE_OTHER,keyValue,&prevValue);
  236. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_SET_MAX_CHAIN",&keyValue);
  237. if (NT_SUCCESS(ntStatus))
  238. status = flSetEnvAll(FL_SET_MAX_CHAIN,keyValue,&prevValue);
  239. ntStatus = TrueffsFetchKeyValue(DriverObject,RegistryPath,L"FL_MARK_DELETE_ON_FLASH",&keyValue);
  240. if (NT_SUCCESS(ntStatus))
  241. status = flSetEnvAll(FL_MARK_DELETE_ON_FLASH,keyValue,&prevValue);
  242. return ntStatus;
  243. #endif /* ENVIRONMENT_VARS*/
  244. //TffsDebugPrint(("Trueffs: TrueffsDetectRegistryValues End\n"));
  245. return STATUS_SUCCESS;
  246. }
  247. ULONG
  248. TrueffsCrashDumpDriverEntry (
  249. PVOID Context
  250. )
  251. /*++
  252. Routine Description:
  253. dump driver entry point
  254. Arguments:
  255. Context - PCRASHDUMP_INIT_DATA
  256. Return Value:
  257. NT Status
  258. --*/
  259. {
  260. PINITIALIZATION_CONTEXT context = Context;
  261. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CrashDumpDriverEntry\n"));
  262. DumpData.CrashInitData = (PCRASHDUMP_INIT_DATA) context->PortConfiguration;
  263. DumpData.StallRoutine = context->StallRoutine;
  264. context->OpenRoutine = TrueffsCrashDumpOpen;
  265. context->WriteRoutine = TrueffsCrashDumpWrite;
  266. context->FinishRoutine = TrueffsCrashDumpFinish;
  267. return STATUS_SUCCESS;
  268. }
  269. BOOLEAN
  270. TrueffsCrashDumpOpen (
  271. IN LARGE_INTEGER PartitionOffset
  272. )
  273. {
  274. TffsDebugPrint((TFFS_DEB_INFO, "Trueffs: CrashDumpOpen: PartitionOffset = 0x%x%08x...\n", PartitionOffset.HighPart, PartitionOffset.LowPart));
  275. DumpData.PartitionOffset = PartitionOffset;
  276. RtlMoveMemory (&DumpData.fdoExtension,DumpData.CrashInitData->cdFdoExtension,sizeof (DEVICE_EXTENSION));
  277. DumpData.MaxBlockSize = DumpData.fdoExtension.BytesPerSector * 256;
  278. return TRUE;
  279. }
  280. NTSTATUS
  281. TrueffsCrashDumpWrite (
  282. IN PLARGE_INTEGER DiskByteOffset,
  283. IN PMDL Mdl
  284. )
  285. {
  286. NTSTATUS status;
  287. ULONG blockSize;
  288. ULONG bytesWritten = 0;
  289. ULONG startingSector;
  290. FLStatus tffsStatus;
  291. IOreq ioreq;
  292. TffsDebugPrint((TFFS_DEB_INFO,
  293. "TrueffsCrashDumpWrite: Write memory at 0x%x for 0x%x bytes\n",
  294. Mdl->MappedSystemVa,
  295. Mdl->ByteCount));
  296. if (Mdl->ByteCount % DumpData.fdoExtension.BytesPerSector) {
  297. // must be complete sectors
  298. TffsDebugPrint((TFFS_DEB_ERROR, "TrueffsCrashDumpWrite ERROR: not writing full sectors\n"));
  299. return STATUS_INVALID_PARAMETER;
  300. }
  301. if ((Mdl->ByteCount / DumpData.fdoExtension.BytesPerSector) > 256) {
  302. // need code to split request up
  303. TffsDebugPrint((TFFS_DEB_ERROR, "TrueffsCrashDumpWrite ERROR: can't handle large write\n"));
  304. return STATUS_INVALID_PARAMETER;
  305. }
  306. do {
  307. if ((Mdl->ByteCount - bytesWritten) > DumpData.MaxBlockSize) {
  308. blockSize = DumpData.MaxBlockSize;
  309. TffsDebugPrint((TFFS_DEB_INFO, "Trueffs: TrueffsCrashDumpWrite: can't do a single write\n"));
  310. } else {
  311. blockSize = Mdl->ByteCount - bytesWritten;
  312. }
  313. status = STATUS_UNSUCCESSFUL;
  314. startingSector = (ULONG)((DumpData.PartitionOffset.QuadPart +
  315. (*DiskByteOffset).QuadPart +
  316. (ULONGLONG) bytesWritten) / DumpData.fdoExtension.BytesPerSector);
  317. ioreq.irHandle = DumpData.fdoExtension.UnitNumber;
  318. ioreq.irSectorNo = startingSector;
  319. ioreq.irSectorCount = blockSize / DumpData.fdoExtension.BytesPerSector;
  320. ioreq.irData = ((PUCHAR) Mdl->MappedSystemVa) + bytesWritten;
  321. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CrashDumpWrite: Starting sector is %x, Number of bytes %x\n",
  322. startingSector,
  323. blockSize));
  324. tffsStatus = flAbsWrite(&ioreq);
  325. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CrashDumpWrite: Write status %Xh\n", tffsStatus));
  326. if (tffsStatus == flOK) {
  327. status = STATUS_SUCCESS;
  328. bytesWritten += blockSize;
  329. }
  330. } while (bytesWritten < Mdl->ByteCount);
  331. return status;
  332. }
  333. VOID
  334. TrueffsCrashDumpFinish (
  335. VOID
  336. )
  337. {
  338. TffsDebugPrint((TFFS_DEB_INFO, "Trueffs: TrueffsCrashDumpFinish\n"));
  339. return;
  340. }
  341. NTSTATUS
  342. TrueffsDispatchSystemControl(
  343. IN PDEVICE_OBJECT DeviceObject,
  344. IN OUT PIRP Irp
  345. )
  346. /*++
  347. Routine Description:
  348. Dispatch routine for IRP_MJ_SYSTEM_CONTROL (WMI) IRPs
  349. Arguments:
  350. DeviceObject - Pointer to the device object for which this IRP applies.
  351. Irp - Pointer to the IRP_MJ_PNP_POWER IRP to dispatch.
  352. Return Value:
  353. NT status.
  354. --*/
  355. {
  356. PIO_STACK_LOCATION thisIrpSp;
  357. NTSTATUS status;
  358. PDEVICE_EXTENSION deviceExtension;
  359. PPDO_EXTENSION pdoExtension;
  360. PDEVICE_EXTENSION_HEADER devExtension;
  361. thisIrpSp = IoGetCurrentIrpStackLocation(Irp);
  362. devExtension = (PDEVICE_EXTENSION_HEADER) DeviceObject->DeviceExtension;
  363. if (IS_FDO(devExtension)) {
  364. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: DispatchSystemControl: WMI IRP (FDO) %Xh not handled. Passing it down.\n",thisIrpSp->MinorFunction));
  365. IoSkipCurrentIrpStackLocation(Irp);
  366. status = IoCallDriver(devExtension->LowerDeviceObject, Irp);
  367. }
  368. else {
  369. if (thisIrpSp->MinorFunction < NUM_WMI_MINOR_FUNCTION) {
  370. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DispatchSystemControl (WMI) %Xh PDO\n",thisIrpSp->MinorFunction));
  371. status = TrueffsWmiSystemControl(DeviceObject, Irp);
  372. } else {
  373. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: DispatchSystemControl (WMI) %Xh PDO unsupported\n",thisIrpSp->MinorFunction));
  374. status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  375. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  376. }
  377. }
  378. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DispatchSystemControl status %Xh\n", status));
  379. return status;
  380. }
  381. NTSTATUS
  382. TrueffsFindDiskOnChip(
  383. IN INTERFACE_TYPE InterfaceType,
  384. IN ULONG BusNumber,
  385. IN ULONG StartSearchAddress,
  386. IN LONG WindowSize,
  387. IN BOOLEAN StartSearch,
  388. OUT PVOID *WindowBase
  389. )
  390. {
  391. ULONG DOCAddressSpace = TFFS_MEMORY_SPACE;
  392. PVOID DOCAddressBase = NULL;
  393. PHYSICAL_ADDRESS DOCAddressMemoryBase;
  394. NTSTATUS status;
  395. ULONG winBase;
  396. volatile UCHAR chipId;
  397. volatile UCHAR toggle1;
  398. volatile UCHAR toggle2;
  399. volatile UCHAR deviceSearch;
  400. DOC2window *memDOC2000WinPtr = NULL;
  401. MDOCPwindow *memWinPtr = NULL;
  402. status = TrueffsTranslateAddress(InterfaceType,
  403. BusNumber,
  404. RtlConvertLongToLargeInteger(StartSearchAddress),
  405. WindowSize,
  406. &DOCAddressSpace,
  407. &DOCAddressBase,
  408. &DOCAddressMemoryBase);
  409. if (!NT_SUCCESS(status)) {
  410. if (status == STATUS_NOT_IMPLEMENTED) {
  411. status = STATUS_UNSUCCESSFUL;
  412. }
  413. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():Failed to alloc memory\n"));
  414. return status;
  415. }
  416. /* DOC2000*/
  417. memDOC2000WinPtr = (DOC2window *) DOCAddressBase;
  418. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, ASIC_NORMAL_MODE);
  419. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, ASIC_NORMAL_MODE);
  420. chipId = tffsReadByte(memDOC2000WinPtr->chipId);
  421. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():After read DOC2000 chipID\n"));
  422. if ((chipId == CHIP_ID_DOC) || (chipId == CHIP_ID_MDOC)) {
  423. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():In chip ID DOC2000 or MDOC\n"));
  424. if (chipId == CHIP_ID_MDOC) {
  425. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():In the MDOC\n"));
  426. toggle1 = tffsReadByte(memDOC2000WinPtr->ECCconfig);
  427. toggle2 = toggle1 ^ tffsReadByte(memDOC2000WinPtr->ECCconfig);
  428. }
  429. else {
  430. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():In the DOC2000\n"));
  431. toggle1 = tffsReadByte(memDOC2000WinPtr->ECCstatus);
  432. toggle2 = toggle1 ^ tffsReadByte(memDOC2000WinPtr->ECCstatus);
  433. }
  434. if (!StartSearch) {
  435. if ((toggle2 & TOGGLE) != 0) {
  436. if (chipId == CHIP_ID_MDOC) {
  437. tffsWriteByte(memDOC2000WinPtr->aliasResolution, ALIAS_RESOLUTION);
  438. }
  439. else {
  440. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():Failed Toggle\n"));
  441. tffsWriteByte(memDOC2000WinPtr->deviceSelector, ALIAS_RESOLUTION);
  442. }
  443. *WindowBase = DOCAddressBase;
  444. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DiskOnChip detected on %Xh\n",StartSearchAddress));
  445. return STATUS_SUCCESS;
  446. }
  447. }
  448. else {
  449. deviceSearch = ( chipId == CHIP_ID_MDOC ) ? tffsReadByte(memDOC2000WinPtr->aliasResolution) :
  450. tffsReadByte(memDOC2000WinPtr->deviceSelector);
  451. if (((toggle2 & TOGGLE) != 0) && (deviceSearch == ALIAS_RESOLUTION)) {
  452. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():Free Window pointer\n"));
  453. TrueffsFreeTranslatedAddress(
  454. DOCAddressBase,
  455. WindowSize,
  456. DOCAddressSpace
  457. );
  458. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Alias detected on %Xh\n",StartSearchAddress));
  459. return STATUS_NOT_IMPLEMENTED;
  460. }
  461. }
  462. }
  463. //Start MDOCP code
  464. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():Start looking for MDOCP\n"));
  465. memWinPtr = (MDOCPwindow *) DOCAddressBase;
  466. memWinPtr->DOCcontrol = (unsigned char)0x05; /* Set RESET Mode */
  467. memWinPtr->DocCntConfirmReg = (unsigned char)0xfa;
  468. chipId = memWinPtr->chipId;
  469. if (chipId == 0x40)
  470. {
  471. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():Identify as MDOCP\n"));
  472. toggle1 = tffsReadByte(memWinPtr->EccCntReg);
  473. toggle2 = toggle1 ^ tffsReadByte(memWinPtr->EccCntReg);
  474. if (!StartSearch)
  475. {
  476. //if ((toggle2 & ECC_CNTRL_TOGGLE_MASK) != 0)
  477. if ((toggle2 & 0x4) != 0)
  478. {
  479. tffsWriteByte(memWinPtr->AliasResolution, ALIAS_RESOLUTION);
  480. *WindowBase = DOCAddressBase;
  481. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MDOCP detected on %Xh\n",StartSearchAddress));
  482. return STATUS_SUCCESS;
  483. }
  484. else
  485. {
  486. deviceSearch = tffsReadByte(memWinPtr->AliasResolution);
  487. //if (((toggle2 & ECC_CNTRL_TOGGLE_MASK) != 0) && (deviceSearch == ALIAS_RESOLUTION))
  488. if (((toggle2 & 0x4) != 0) && (deviceSearch == ALIAS_RESOLUTION))
  489. {
  490. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c :TrueffsFindDiskOnChip():MDOCP Failed togfle - Free memory\n"));
  491. TrueffsFreeTranslatedAddress(
  492. DOCAddressBase,
  493. WindowSize,
  494. DOCAddressSpace
  495. );
  496. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Alias detected on %Xh\n",StartSearchAddress));
  497. return STATUS_NOT_IMPLEMENTED;
  498. }
  499. }
  500. }
  501. }
  502. TrueffsFreeTranslatedAddress(
  503. DOCAddressBase,
  504. WindowSize,
  505. DOCAddressSpace
  506. );
  507. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DiskOnChip not detected on %Xh\n", StartSearchAddress));
  508. return STATUS_UNSUCCESSFUL;
  509. }
  510. NTSTATUS
  511. TrueffsCheckDiskOnChip(
  512. IN INTERFACE_TYPE InterfaceType,
  513. IN ULONG BusNumber,
  514. IN ULONG StartSearchAddress,
  515. IN LONG WindowSize,
  516. OUT PVOID *WindowBase,
  517. OUT PULONG AddressSpace
  518. )
  519. {
  520. ULONG DOCAddressSpace = TFFS_MEMORY_SPACE;
  521. PVOID DOCAddressBase = NULL;
  522. PHYSICAL_ADDRESS DOCAddressMemoryBase;
  523. NTSTATUS status;
  524. volatile UCHAR chipId;
  525. volatile UCHAR toggle1;
  526. volatile UCHAR toggle2;
  527. DOC2window *memDOC2000WinPtr;
  528. MDOCPwindow *memWinPtr;
  529. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c: TrueffsCheckDiskOnChip() Started ...\n"));
  530. status = TrueffsTranslateAddress(InterfaceType,
  531. BusNumber,
  532. RtlConvertLongToLargeInteger(StartSearchAddress),
  533. WindowSize,
  534. &DOCAddressSpace,
  535. &DOCAddressBase,
  536. &DOCAddressMemoryBase);
  537. if (!NT_SUCCESS(status)) {
  538. return status;
  539. }
  540. memDOC2000WinPtr = (DOC2window *) DOCAddressBase;
  541. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, 0x84);
  542. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, 0x84);
  543. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, 0x85);
  544. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, 0x85);
  545. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c: TrueffsCheckDiskOnChip() DOC2000 read chip ID\n"));
  546. chipId = tffsReadByte(memDOC2000WinPtr->chipId);
  547. if ((chipId == CHIP_ID_DOC) || (chipId == CHIP_ID_MDOC)) {
  548. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c: TrueffsCheckDiskOnChip() DOC2000 chipID = 0x%x\n", chipId));
  549. if (chipId == CHIP_ID_MDOC) {
  550. toggle1 = tffsReadByte(memDOC2000WinPtr->ECCconfig);
  551. toggle2 = toggle1 ^ tffsReadByte(memDOC2000WinPtr->ECCconfig);
  552. }
  553. else {
  554. toggle1 = tffsReadByte(memDOC2000WinPtr->ECCstatus);
  555. toggle2 = toggle1 ^ tffsReadByte(memDOC2000WinPtr->ECCstatus);
  556. }
  557. if ((toggle2 & TOGGLE) != 0) {
  558. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c: TrueffsCheckDiskOnChip() DOC2000 Finished toggle successfuly\n"));
  559. *WindowBase = DOCAddressBase;
  560. *AddressSpace = DOCAddressSpace;
  561. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DiskOnChip2000 found on %Xh\n",StartSearchAddress));
  562. return STATUS_SUCCESS;
  563. }
  564. }
  565. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c: TrueffsCheckDiskOnChip() MDOCPLUS Start....\n"));
  566. memWinPtr = (MDOCPwindow *) DOCAddressBase;
  567. tffsWriteByte(memWinPtr->DOCcontrol, (unsigned char)0x04);
  568. tffsWriteByte(memWinPtr->DocCntConfirmReg, (unsigned char)0xfb);
  569. tffsWriteByte(memWinPtr->DOCcontrol, (unsigned char)0x05);
  570. tffsWriteByte(memWinPtr->DocCntConfirmReg, (unsigned char)0xfa);
  571. chipId = tffsReadByte(memWinPtr->chipId);
  572. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c: TrueffsCheckDiskOnChip() MDOCPLUS chipID = 0x%x\n", chipId));
  573. //if (chipId == CHIP_ID_MDOCP)
  574. if (chipId == 0x40)
  575. {
  576. toggle1 = tffsReadByte(memWinPtr->EccCntReg);
  577. toggle2 = toggle1 ^ tffsReadByte(memWinPtr->EccCntReg);
  578. //if ((toggle2 & ECC_CNTRL_TOGGLE_MASK) != 0)
  579. if ((toggle2 & 0x4) != 0)
  580. {
  581. *WindowBase = DOCAddressBase;
  582. *AddressSpace = DOCAddressSpace;
  583. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MDOCPLUS found on %Xh\n",StartSearchAddress));
  584. return STATUS_SUCCESS;
  585. }
  586. }
  587. TrueffsFreeTranslatedAddress(
  588. DOCAddressBase,
  589. WindowSize,
  590. DOCAddressSpace
  591. );
  592. return STATUS_UNSUCCESSFUL;
  593. }
  594. VOID
  595. TrueffsResetDiskOnChip(
  596. IN INTERFACE_TYPE InterfaceType,
  597. IN ULONG BusNumber,
  598. IN ULONG StartSearchAddress,
  599. IN LONG WindowSize
  600. )
  601. {
  602. ULONG DOCAddressSpace = TFFS_MEMORY_SPACE;
  603. PVOID DOCAddressBase = NULL;
  604. PHYSICAL_ADDRESS DOCAddressMemoryBase;
  605. NTSTATUS status;
  606. DOC2window *memDOC2000WinPtr;
  607. MDOCPwindow *memWinPtr;
  608. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c:TrueffsResetDiskOnChip()b start\n"));
  609. status = TrueffsTranslateAddress(InterfaceType,
  610. BusNumber,
  611. RtlConvertLongToLargeInteger(StartSearchAddress),
  612. WindowSize,
  613. &DOCAddressSpace,
  614. &DOCAddressBase,
  615. &DOCAddressMemoryBase);
  616. if (!NT_SUCCESS(status)) {
  617. return;
  618. }
  619. /* DOC2000 CHANGES*/
  620. memDOC2000WinPtr = (DOC2window *) DOCAddressBase;
  621. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, 0x84);
  622. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, 0x84);
  623. memWinPtr = (MDOCPwindow *) DOCAddressBase;
  624. tffsWriteByte(memWinPtr->DOCcontrol,(unsigned char)0x04 );
  625. tffsWriteByte(memWinPtr->DocCntConfirmReg,(unsigned char)0xfb );
  626. TrueffsFreeTranslatedAddress(
  627. DOCAddressBase,
  628. WindowSize,
  629. DOCAddressSpace
  630. );
  631. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: tffsport.c:TrueffsResetDiskOnChip()b End\n"));
  632. return;
  633. }
  634. NTSTATUS
  635. TrueffsStartSubDevice(
  636. IN UCHAR deviceNo,
  637. IN UCHAR partitionNumber,
  638. IN PDEVICE_EXTENSION deviceExtension,
  639. IN PCM_RESOURCE_LIST ResourceList,
  640. IN BOOLEAN CheckResources
  641. )
  642. {
  643. NTSTATUS status = STATUS_UNSUCCESSFUL;
  644. ExAcquireFastMutex(&driveInfoReferenceMutex);
  645. deviceExtension->UnitNumber = (partitionNumber << 4) + deviceNo;
  646. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  647. status = TrueffsCreateSymblicLinks(deviceExtension);
  648. if (!NT_SUCCESS(status)) {
  649. return STATUS_UNSUCCESSFUL;
  650. }
  651. }
  652. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartDevice OK\n"));
  653. ExReleaseFastMutex(&driveInfoReferenceMutex);
  654. return STATUS_SUCCESS;
  655. }
  656. NTSTATUS
  657. TrueffsDetectDiskOnChip(
  658. IN PDRIVER_OBJECT DriverObject,
  659. IN PUNICODE_STRING RegistryPath
  660. )
  661. {
  662. ULONG cmResourceListSize;
  663. PCM_RESOURCE_LIST cmResourceList = NULL;
  664. PCM_FULL_RESOURCE_DESCRIPTOR cmFullResourceDescriptor;
  665. PCM_PARTIAL_RESOURCE_LIST cmPartialResourceList;
  666. PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartialDescriptors;
  667. BOOLEAN conflictDetected;
  668. PDEVICE_OBJECT detectedPhysicalDeviceObject;
  669. PDEVICE_EXTENSION fdoExtensions[VOLUMES];
  670. NTSTATUS status;
  671. ULONG legacyDetection = 0;
  672. ULONG searchBase, aliasSearchBase, aliasCounter;
  673. PVOID mappedWindowBase = NULL;
  674. KIRQL cIrql;
  675. BOOLEAN startSearch = FALSE;
  676. int noOfDevices = 0;
  677. int deviceNo = 0;
  678. UCHAR currSockets = 0;
  679. int index = 0;
  680. CM_RESOURCE_LIST arrayResourceList[VOLUMES];
  681. ULONG prevValue;
  682. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DetectDiskOnChip\n"));
  683. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DetectDiskOnChip, go to Registry\n"));
  684. // Set Registry Vars to TrueFFS
  685. TrueffsDetectRegistryValues(DriverObject,RegistryPath);
  686. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DetectDiskOnChip, back from Registry\n"));
  687. if (!TrueffsOkToDetectLegacy(DriverObject)) {
  688. // legacy detection is not enabled
  689. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: DetectDiskOnChip: detection is not enabled\n"));
  690. return STATUS_SUCCESS;
  691. }
  692. // disable legacy detection for next boot
  693. TrueffsGetParameterFromServiceSubKey (
  694. DriverObject,
  695. LEGACY_DETECTION,
  696. REG_DWORD,
  697. FALSE,
  698. (PVOID) &legacyDetection,
  699. sizeof (legacyDetection)
  700. );
  701. cmResourceListSize = sizeof (CM_RESOURCE_LIST);
  702. cmResourceList = ExAllocatePoolWithTag (PagedPool, cmResourceListSize, TFFSPORT_POOL_TAG);
  703. if (cmResourceList == NULL){
  704. status = STATUS_NO_MEMORY;
  705. goto GetOut;
  706. }
  707. RtlZeroMemory(cmResourceList, cmResourceListSize);
  708. for(index = 0; index < VOLUMES; index++){
  709. fdoExtensions[index] = NULL;
  710. //arrayResourceList[index] = ExAllocatePoolWithTag (PagedPool, cmResourceListSize, TFFSPORT_POOL_TAG);
  711. //RtlZeroMemory(arrayResourceList[index], cmResourceListSize );
  712. }
  713. RtlZeroMemory(arrayResourceList, cmResourceListSize * VOLUMES);
  714. // Build resource requirement list
  715. cmResourceList->Count = 1;
  716. cmFullResourceDescriptor = cmResourceList->List;
  717. cmFullResourceDescriptor->InterfaceType = DISKONCHIP_INTERFACE;
  718. cmFullResourceDescriptor->BusNumber = DISKONCHIP_BUSNUMBER;
  719. cmPartialResourceList = &cmFullResourceDescriptor->PartialResourceList;
  720. cmPartialResourceList->Version = 1;
  721. cmPartialResourceList->Revision = 1;
  722. cmPartialResourceList->Count = 1;
  723. cmPartialDescriptors = cmPartialResourceList->PartialDescriptors;
  724. cmPartialDescriptors[0].Type = CmResourceTypeMemory;
  725. cmPartialDescriptors[0].ShareDisposition = CmResourceShareShared;
  726. cmPartialDescriptors[0].Flags = CM_RESOURCE_MEMORY_READ_ONLY;
  727. cmPartialDescriptors[0].u.Memory.Length = DISKONCHIP_WINDOW_SIZE;
  728. for(searchBase = START_SEARCH_ADDRESS; searchBase < END_SEARCH_ADDRESS ; searchBase += DISKONCHIP_WINDOW_SIZE) {
  729. cmPartialDescriptors[0].u.Memory.Start.QuadPart = searchBase;
  730. // check to see if the resource is available
  731. status = IoReportResourceForDetection (
  732. DriverObject,
  733. cmResourceList,
  734. cmResourceListSize,
  735. NULL,
  736. NULL,
  737. 0,
  738. &conflictDetected
  739. );
  740. if (!NT_SUCCESS(status) || conflictDetected) {
  741. if (NT_SUCCESS(status)) {
  742. IoReportResourceForDetection (
  743. DriverObject,
  744. NULL,
  745. 0,
  746. NULL,
  747. NULL,
  748. 0,
  749. &conflictDetected
  750. );
  751. status = STATUS_UNSUCCESSFUL;
  752. }
  753. }
  754. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IoReportResourceForDetection with status %Xh\n",status));
  755. if (!NT_SUCCESS (status)) {
  756. continue;
  757. }
  758. TrueffsResetDiskOnChip(cmFullResourceDescriptor->InterfaceType,cmFullResourceDescriptor->BusNumber,searchBase,DISKONCHIP_WINDOW_SIZE);
  759. // release the resources
  760. IoReportResourceForDetection (
  761. DriverObject,
  762. NULL,
  763. 0,
  764. NULL,
  765. NULL,
  766. 0,
  767. &conflictDetected
  768. );
  769. // check to see if the resource is available
  770. status = IoReportResourceForDetection (
  771. DriverObject,
  772. cmResourceList,
  773. cmResourceListSize,
  774. NULL,
  775. NULL,
  776. 0,
  777. &conflictDetected
  778. );
  779. if (!NT_SUCCESS(status) || conflictDetected) {
  780. if (NT_SUCCESS(status)) {
  781. IoReportResourceForDetection (
  782. DriverObject,
  783. NULL,
  784. 0,
  785. NULL,
  786. NULL,
  787. 0,
  788. &conflictDetected
  789. );
  790. status = STATUS_UNSUCCESSFUL;
  791. }
  792. }
  793. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IoReportResourceForDetection with status %Xh\n",status));
  794. // if (!NT_SUCCESS (status)) {
  795. // continue;
  796. // }
  797. if (NT_SUCCESS (status)) {
  798. status = TrueffsFindDiskOnChip(cmFullResourceDescriptor->InterfaceType,cmFullResourceDescriptor->BusNumber,searchBase,DISKONCHIP_WINDOW_SIZE, startSearch,&mappedWindowBase);
  799. }
  800. else{
  801. continue;
  802. }
  803. // release the resources we have grab, IoReportDetectedDevice()
  804. // will grab them for us again when we call and it will grab them
  805. // on behalf of the detected PDO.
  806. IoReportResourceForDetection (
  807. DriverObject,
  808. NULL,
  809. 0,
  810. NULL,
  811. NULL,
  812. 0,
  813. &conflictDetected
  814. );
  815. if (NT_SUCCESS (status)) {
  816. detectedPhysicalDeviceObject = NULL;
  817. status = IoReportDetectedDevice(DriverObject,
  818. Isa,
  819. 0,
  820. 0,
  821. cmResourceList,
  822. NULL,
  823. FALSE,
  824. &detectedPhysicalDeviceObject);
  825. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IoReportDetectedDevice returned status %Xh\n",status));
  826. if (NT_SUCCESS (status)) {
  827. // create a FDO and attach it to the detected PDO
  828. status = TrueffsCreateDevObject(
  829. DriverObject,
  830. detectedPhysicalDeviceObject,
  831. &fdoExtensions[noOfDevices]
  832. );
  833. }
  834. if (NT_SUCCESS (status)) {
  835. status = TrueffsStartDeviceOnDetect(fdoExtensions[noOfDevices],cmResourceList,TRUE);
  836. if (NT_SUCCESS (status)) {
  837. memcpy(&arrayResourceList[noOfDevices++],cmResourceList, cmResourceListSize);
  838. //moti tffscpy(&arrayResourceList[noOfDevices++],cmResourceList, cmResourceListSize);
  839. //tffscpy(arrayResourceList[noOfDevices++],cmResourceList, cmResourceListSize);
  840. }
  841. }
  842. }
  843. }
  844. //Mounting all devices includes sub handles
  845. for(deviceNo = 0;deviceNo < noOfDevices;deviceNo++) {
  846. FLStatus flStatus = flOK;
  847. status = STATUS_SUCCESS;
  848. status = TrueffsMountMedia(fdoExtensions[deviceNo]);
  849. if (!NT_SUCCESS (status)) {
  850. // go through the remove sequence
  851. if (fdoExtensions[deviceNo]) {
  852. IoDetachDevice(fdoExtensions[deviceNo]->LowerDeviceObject);
  853. IoDeleteDevice(fdoExtensions[deviceNo]->DeviceObject);
  854. }
  855. continue;
  856. }
  857. else {
  858. IOreq ioreq;
  859. int partitionNumber = 0;
  860. int noOfPartitions = 0;
  861. ioreq.irHandle = deviceNo;
  862. flStatus= flCountVolumes(&ioreq);
  863. if(flStatus == flOK)
  864. noOfPartitions = ioreq.irFlags;
  865. else
  866. noOfPartitions = 1;
  867. KeAcquireSpinLock(&fdoExtensions[deviceNo]->ExtensionDataSpinLock,&cIrql);
  868. fdoExtensions[deviceNo]->DeviceFlags &= ~DEVICE_FLAG_STOPPED;
  869. fdoExtensions[deviceNo]->DeviceFlags |= DEVICE_FLAG_STARTED;
  870. KeReleaseSpinLock(&fdoExtensions[deviceNo]->ExtensionDataSpinLock,cIrql);
  871. //Handle sub partitions
  872. for(partitionNumber = 1;partitionNumber < noOfPartitions;partitionNumber++){
  873. PDEVICE_EXTENSION fdoExtension = NULL;
  874. status = STATUS_SUCCESS;
  875. // release the resources we have grab, IoReportDetectedDevice()
  876. // will grab them for us again when we call and it will grab them
  877. // on behalf of the detected PDO.
  878. /* IoReportResourceForDetection (
  879. DriverObject,
  880. NULL,
  881. 0,
  882. NULL,
  883. NULL,
  884. 0,
  885. &conflictDetected
  886. );
  887. */
  888. detectedPhysicalDeviceObject = NULL;
  889. status = IoReportDetectedDevice(DriverObject,
  890. Isa,
  891. 0,
  892. 0,
  893. &arrayResourceList[deviceNo],
  894. //arrayResourceList[deviceNo],
  895. NULL,
  896. FALSE,
  897. &detectedPhysicalDeviceObject);
  898. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IoReportDetectedDevice returned status %Xh\n",status));
  899. if (NT_SUCCESS (status)) {
  900. // create a FDO and attach it to the detected PDO
  901. status = TrueffsCreateDevObject(
  902. DriverObject,
  903. detectedPhysicalDeviceObject,
  904. &fdoExtension
  905. );
  906. }
  907. if (NT_SUCCESS (status)) {
  908. status = TrueffsStartSubDevice((unsigned char)deviceNo,
  909. (unsigned char)partitionNumber,
  910. fdoExtension,
  911. &arrayResourceList[deviceNo],
  912. //arrayResourceList[deviceNo],
  913. TRUE);
  914. }
  915. if (NT_SUCCESS (status)) {
  916. status = TrueffsMountMedia(fdoExtension);
  917. if (!NT_SUCCESS (status)) {
  918. // go through the remove sequence
  919. if (fdoExtension) {
  920. IoDetachDevice(fdoExtension->LowerDeviceObject);
  921. IoDeleteDevice(fdoExtension->DeviceObject);
  922. }
  923. continue;
  924. }
  925. else{
  926. KeAcquireSpinLock(&fdoExtension->ExtensionDataSpinLock,&cIrql);
  927. fdoExtension->DeviceFlags &= ~DEVICE_FLAG_STOPPED;
  928. fdoExtension->DeviceFlags |= DEVICE_FLAG_STARTED;
  929. KeReleaseSpinLock(&fdoExtension->ExtensionDataSpinLock,cIrql);
  930. }
  931. }
  932. }
  933. }
  934. }
  935. GetOut:
  936. if (cmResourceList) {
  937. ExFreePool (cmResourceList);
  938. cmResourceList = NULL;
  939. }
  940. for(index = 0; index < VOLUMES; index++){
  941. fdoExtensions[index] = NULL;
  942. }
  943. #ifdef ENVIRONMENT_VARS
  944. for ( currSockets = 0; currSockets < SOCKETS; currSockets++) {
  945. if (VerifyWriteState[currSockets])
  946. status = flSetEnvSocket(FL_VERIFY_WRITE_BDTL,currSockets,VerifyWriteState[currSockets],&prevValue);
  947. }
  948. #endif /*ENVIRONMENT_VARS */
  949. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DetectDiskOnChip with status %Xh\n",status));
  950. return status;
  951. }
  952. NTSTATUS
  953. TrueffsTranslateAddress(
  954. IN INTERFACE_TYPE InterfaceType,
  955. IN ULONG BusNumber,
  956. IN PHYSICAL_ADDRESS StartAddress,
  957. IN LONG Length,
  958. IN OUT PULONG AddressSpace,
  959. OUT PVOID *TranslatedAddress,
  960. OUT PPHYSICAL_ADDRESS TranslatedMemoryAddress
  961. )
  962. /*++
  963. Routine Description:
  964. translate i/o address
  965. Arguments:
  966. InterfaceType - bus interface
  967. BusNumber - bus number
  968. StartAddress - address to translate
  969. Length - number of byte to translate
  970. AddressSpace - address space for the given address
  971. Return Value:
  972. AddressSpace - address space for the translated address
  973. TranslatedAddress - translated address
  974. TranslatedMemoryAddress - tranlated memory address if translated to memory space
  975. NT Status
  976. --*/
  977. {
  978. PHYSICAL_ADDRESS translatedAddress;
  979. *TranslatedAddress = NULL;
  980. TranslatedMemoryAddress->QuadPart = (ULONGLONG) NULL;
  981. if (HalTranslateBusAddress(InterfaceType,
  982. BusNumber,
  983. StartAddress,
  984. AddressSpace,
  985. &translatedAddress)) {
  986. if (*AddressSpace == TFFS_IO_SPACE) {
  987. *TranslatedMemoryAddress = translatedAddress;
  988. *TranslatedAddress = (PVOID) translatedAddress.QuadPart;
  989. } else if (*AddressSpace == TFFS_MEMORY_SPACE) {
  990. // translated address is in memory space,
  991. *TranslatedMemoryAddress = translatedAddress;
  992. *TranslatedAddress = MmMapIoSpace(
  993. translatedAddress,
  994. Length,
  995. FALSE);
  996. }
  997. }
  998. if (*TranslatedAddress) {
  999. return STATUS_SUCCESS;
  1000. } else {
  1001. return STATUS_INVALID_PARAMETER;
  1002. }
  1003. }
  1004. VOID
  1005. TrueffsFreeTranslatedAddress(
  1006. IN PVOID TranslatedAddress,
  1007. IN LONG Length,
  1008. IN ULONG AddressSpace
  1009. )
  1010. /*++
  1011. Routine Description:
  1012. free resources created for a translated address
  1013. Arguments:
  1014. TranslatedAddress - translated address
  1015. Length - number of byte to translated
  1016. AddressSpace - address space for the translated address
  1017. Return Value:
  1018. None
  1019. --*/
  1020. {
  1021. if (TranslatedAddress) {
  1022. if (AddressSpace == TFFS_MEMORY_SPACE) {
  1023. MmUnmapIoSpace (
  1024. TranslatedAddress,
  1025. Length
  1026. );
  1027. }
  1028. }
  1029. return;
  1030. }
  1031. NTSTATUS
  1032. TrueffsAddDevice(
  1033. PDRIVER_OBJECT DriverObject,
  1034. PDEVICE_OBJECT Pdo
  1035. )
  1036. /*++
  1037. Routine Description:
  1038. This is our PNP AddDevice called with the PDO ejected from the bus driver
  1039. Arguments:
  1040. Argument1 - Driver Object.
  1041. Argument2 - PDO.
  1042. Return Value:
  1043. A valid return code for a DriverEntry routine.
  1044. --*/
  1045. {
  1046. NTSTATUS status;
  1047. PDEVICE_EXTENSION fdoExtension;
  1048. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: AddDevice\n"));
  1049. status = TrueffsCreateDevObject (DriverObject,Pdo,&fdoExtension);
  1050. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: AddDevice with status %Xh\n", status));
  1051. return status;
  1052. }
  1053. NTSTATUS
  1054. TrueffsCreateDevObject(
  1055. IN PDRIVER_OBJECT DriverObject,
  1056. IN PDEVICE_OBJECT Pdo,
  1057. OUT PDEVICE_EXTENSION *FdoExtension
  1058. )
  1059. /*++
  1060. Routine Description:
  1061. This routine creates an object for the physical device specified and
  1062. sets up the deviceExtension.
  1063. Arguments:
  1064. DriverObject - Pointer to driver object created by system.
  1065. PhysicalDeviceObject = PDO we should attach to.
  1066. Return Value:
  1067. NTSTATUS
  1068. --*/
  1069. {
  1070. PDEVICE_EXTENSION deviceExtension;
  1071. NTSTATUS status;
  1072. PDEVICE_OBJECT deviceObject = NULL;
  1073. STRING deviceName;
  1074. CCHAR deviceNameBuffer[64];
  1075. UNICODE_STRING unicodeDeviceNameString;
  1076. UNICODE_STRING driverName;
  1077. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CreateDevObject\n"));
  1078. sprintf(deviceNameBuffer, "\\Device\\TffsPort%d",TrueffsNextDeviceNumber_tffsport);
  1079. RtlInitString(&deviceName, deviceNameBuffer);
  1080. status = RtlAnsiStringToUnicodeString(&unicodeDeviceNameString,
  1081. &deviceName,
  1082. TRUE);
  1083. if (!NT_SUCCESS (status)) {
  1084. return status;
  1085. }
  1086. status = IoCreateDevice(DriverObject,
  1087. sizeof(DEVICE_EXTENSION),
  1088. &unicodeDeviceNameString, // our name
  1089. FILE_DEVICE_CONTROLLER,
  1090. FILE_DEVICE_SECURE_OPEN,
  1091. FALSE,
  1092. &deviceObject);
  1093. RtlFreeUnicodeString (&unicodeDeviceNameString);
  1094. if (!NT_SUCCESS(status)) {
  1095. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: CreateDevObject: IoCreateDevice failed with status %Xh\n",status));
  1096. return status;
  1097. }
  1098. else {
  1099. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Created FDO %Xh\n",deviceObject));
  1100. }
  1101. deviceExtension = deviceObject->DeviceExtension;
  1102. RtlZeroMemory(deviceExtension,sizeof(DEVICE_EXTENSION));
  1103. if (Pdo != NULL) {
  1104. if ((deviceExtension->LowerDeviceObject =
  1105. IoAttachDeviceToDeviceStack(deviceObject,Pdo))==NULL){
  1106. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: CreateDevObject: cannot attach device\n"));
  1107. IoDeleteDevice(deviceObject);
  1108. return status;
  1109. }
  1110. }
  1111. KeInitializeSemaphore(&deviceExtension->requestSemaphore,0L,MAXLONG);
  1112. KeInitializeSpinLock(&deviceExtension->listSpinLock);
  1113. InitializeListHead(&deviceExtension->listEntry);
  1114. KeInitializeSpinLock(&deviceExtension->ExtensionDataSpinLock);
  1115. KeInitializeEvent(&deviceExtension->PendingIRPEvent, SynchronizationEvent, FALSE);
  1116. deviceExtension->threadReferenceCount = -1;
  1117. deviceExtension->pcmciaParams.physWindow = 0;
  1118. deviceExtension->pcmciaParams.windowSize = 0;
  1119. deviceExtension->pcmciaParams.windowBase = NULL;
  1120. deviceObject->Flags |= DO_DIRECT_IO;
  1121. deviceExtension->DeviceObject = deviceObject;
  1122. deviceExtension->MainPdo = Pdo;
  1123. deviceExtension->DriverObject = DriverObject;
  1124. deviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
  1125. deviceObject->Flags &=~DO_DEVICE_INITIALIZING;
  1126. deviceExtension->DeviceFlags |= DEVICE_FLAG_STOPPED;
  1127. #if 0 //Pcmcia cards don't have removable media
  1128. RtlInitUnicodeString(&driverName, L"\\Driver\\Pcmcia");
  1129. if (!RtlCompareUnicodeString(&Pdo->DriverObject->DriverName,&driverName,TRUE)) {
  1130. deviceExtension->removableMedia = TRUE;
  1131. }
  1132. #endif
  1133. deviceExtension->TrueffsDeviceNumber = TrueffsNextDeviceNumber_tffsport;
  1134. TrueffsNextDeviceNumber_tffsport++;
  1135. deviceExtension->ScsiDeviceType = DIRECT_ACCESS_DEVICE;
  1136. *FdoExtension = deviceExtension;
  1137. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CreateDevObject with status %Xh\n",status));
  1138. return status;
  1139. }
  1140. NTSTATUS
  1141. TrueffsStartDeviceOnDetect(
  1142. IN PDEVICE_EXTENSION deviceExtension,
  1143. IN PCM_RESOURCE_LIST ResourceList,
  1144. IN BOOLEAN CheckResources
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. This is our START_DEVICE, called when we get an IPR_MN_START_DEVICE.
  1149. Arguments:
  1150. DeviceObject
  1151. Return Value:
  1152. NTSTATUS
  1153. --*/
  1154. {
  1155. PCM_FULL_RESOURCE_DESCRIPTOR fullResourceList;
  1156. PCM_PARTIAL_RESOURCE_LIST partialResourceList;
  1157. PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptors;
  1158. NTSTATUS status = STATUS_UNSUCCESSFUL;
  1159. ULONG i;
  1160. ULONG j;
  1161. PVOID mappedWindowBase = NULL;
  1162. ULONG addressSpace;
  1163. // assume we have DOC
  1164. ExAcquireFastMutex(&driveInfoReferenceMutex);
  1165. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  1166. for (i = 0; i < DOC_DRIVES; i++) {
  1167. if (driveInfo[i].fdoExtension == NULL) {
  1168. deviceExtension->UnitNumber = i;
  1169. break;
  1170. }
  1171. }
  1172. }
  1173. // Check resources
  1174. if (CheckResources) {
  1175. if (ResourceList == NULL || ResourceList->List == NULL) {
  1176. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartDevice: No resources !\n"));
  1177. goto exitStartDevice;
  1178. }
  1179. fullResourceList = ResourceList->List;
  1180. for (i = 0; i < ResourceList->Count; i++) {
  1181. partialResourceList = &(fullResourceList->PartialResourceList);
  1182. partialDescriptors = fullResourceList->PartialResourceList.PartialDescriptors;
  1183. for (j = 0; j < partialResourceList->Count; j++) {
  1184. if (partialDescriptors[j].Type == CmResourceTypeMemory) {
  1185. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Memory %Xh Size %Xh Interf %Xh Bus %Xh\n",
  1186. partialDescriptors[j].u.Memory.Start.LowPart,
  1187. partialDescriptors[j].u.Memory.Length,
  1188. fullResourceList->InterfaceType,
  1189. fullResourceList->BusNumber));
  1190. status = TrueffsCheckDiskOnChip(
  1191. fullResourceList->InterfaceType,
  1192. fullResourceList->BusNumber,
  1193. partialDescriptors[j].u.Memory.Start.LowPart,
  1194. partialDescriptors[j].u.Memory.Length,
  1195. &mappedWindowBase,
  1196. &addressSpace
  1197. );
  1198. if (NT_SUCCESS(status)) {
  1199. deviceExtension->pcmciaParams.windowBase = mappedWindowBase;
  1200. deviceExtension->pcmciaParams.windowSize = partialDescriptors[j].u.Memory.Length;
  1201. deviceExtension->pcmciaParams.addressSpace = addressSpace;
  1202. deviceExtension->pcmciaParams.phWindowBase = RtlConvertLongToLargeInteger(partialDescriptors[j].u.Memory.Start.LowPart);
  1203. deviceExtension->pcmciaParams.physWindow = partialDescriptors[j].u.Memory.Start.QuadPart;
  1204. deviceExtension->pcmciaParams.InterfaceType = fullResourceList->InterfaceType;
  1205. deviceExtension->pcmciaParams.BusNumber = fullResourceList->BusNumber;
  1206. updateDocSocketParams(deviceExtension);
  1207. goto goodResources;
  1208. }
  1209. }
  1210. }
  1211. fullResourceList = (PCM_FULL_RESOURCE_DESCRIPTOR) (partialDescriptors + partialResourceList->Count);
  1212. }
  1213. // DiskOnChip was not found, assume this is PCMCIA
  1214. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  1215. for (i = DOC_DRIVES; i < SOCKETS; i++) {
  1216. if (driveInfo[i].fdoExtension == NULL) {
  1217. deviceExtension->UnitNumber = i;
  1218. break;
  1219. }
  1220. }
  1221. }
  1222. fullResourceList = ResourceList->List;
  1223. for (i = 0; i < ResourceList->Count; i++) {
  1224. partialResourceList = &(fullResourceList->PartialResourceList);
  1225. partialDescriptors = fullResourceList->PartialResourceList.PartialDescriptors;
  1226. for (j = 0; j < partialResourceList->Count; j++) {
  1227. if (partialDescriptors[j].Type == CmResourceTypeMemory) {
  1228. PHYSICAL_ADDRESS AddressMemoryBase;
  1229. ULONG PcmciaAddressSpace = TFFS_MEMORY_SPACE;
  1230. deviceExtension->pcmciaParams.windowSize = partialDescriptors[j].u.Memory.Length;
  1231. deviceExtension->pcmciaParams.phWindowBase = RtlConvertLongToLargeInteger(partialDescriptors[j].u.Memory.Start.LowPart);
  1232. deviceExtension->pcmciaParams.physWindow = partialDescriptors[j].u.Memory.Start.QuadPart;
  1233. deviceExtension->pcmciaParams.InterfaceType = fullResourceList->InterfaceType;
  1234. deviceExtension->pcmciaParams.BusNumber = fullResourceList->BusNumber;
  1235. mappedWindowBase = NULL;
  1236. status = TrueffsTranslateAddress(
  1237. deviceExtension->pcmciaParams.InterfaceType,
  1238. deviceExtension->pcmciaParams.BusNumber,
  1239. deviceExtension->pcmciaParams.phWindowBase,
  1240. deviceExtension->pcmciaParams.windowSize,
  1241. &PcmciaAddressSpace,
  1242. &mappedWindowBase,
  1243. &AddressMemoryBase);
  1244. deviceExtension->pcmciaParams.windowBase = mappedWindowBase;
  1245. deviceExtension->pcmciaParams.addressSpace = PcmciaAddressSpace;
  1246. if (!NT_SUCCESS(status)) {
  1247. goto exitStartDevice;
  1248. }
  1249. status = updatePcmciaSocketParams(deviceExtension);
  1250. if (NT_SUCCESS(status)) {
  1251. goto goodResources;
  1252. }
  1253. }
  1254. }
  1255. fullResourceList = (PCM_FULL_RESOURCE_DESCRIPTOR) (partialDescriptors + partialResourceList->Count);
  1256. }
  1257. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartDevice: pnp manager gave me bad resources!\n"));
  1258. status = STATUS_INVALID_PARAMETER;
  1259. goto exitStartDevice;
  1260. }
  1261. goodResources:
  1262. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Window at %Xh\n",mappedWindowBase));
  1263. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  1264. // Create legacy object names
  1265. status = TrueffsCreateSymblicLinks(deviceExtension);
  1266. if (!NT_SUCCESS(status)) {
  1267. goto exitStartDevice;
  1268. }
  1269. }
  1270. ExReleaseFastMutex(&driveInfoReferenceMutex);
  1271. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartDevice OK\n"));
  1272. return STATUS_SUCCESS;
  1273. exitStartDevice:
  1274. if (!NT_SUCCESS(status)) {
  1275. TrueffsStopRemoveDevice(deviceExtension);
  1276. TrueffsDeleteSymblicLinks(deviceExtension);
  1277. }
  1278. ExReleaseFastMutex(&driveInfoReferenceMutex);
  1279. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartDevice: exit with status %Xh\n",status));
  1280. return status;
  1281. }
  1282. //==============================================
  1283. NTSTATUS
  1284. TrueffsStartDevice(
  1285. IN PDEVICE_EXTENSION deviceExtension,
  1286. IN PCM_RESOURCE_LIST ResourceList,
  1287. IN BOOLEAN CheckResources
  1288. )
  1289. /*++
  1290. Routine Description:
  1291. This is our START_DEVICE, called when we get an IPR_MN_START_DEVICE.
  1292. Arguments:
  1293. DeviceObject
  1294. Return Value:
  1295. NTSTATUS
  1296. --*/
  1297. {
  1298. PCM_FULL_RESOURCE_DESCRIPTOR fullResourceList;
  1299. PCM_PARTIAL_RESOURCE_LIST partialResourceList;
  1300. PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptors;
  1301. NTSTATUS status = STATUS_UNSUCCESSFUL;
  1302. ULONG i;
  1303. ULONG j;
  1304. PVOID mappedWindowBase = NULL;
  1305. ULONG addressSpace;
  1306. // assume we have DOC
  1307. ExAcquireFastMutex(&driveInfoReferenceMutex);
  1308. // Check resources
  1309. if (CheckResources) {
  1310. if (ResourceList == NULL || ResourceList->List == NULL) {
  1311. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartDevice: No resources !\n"));
  1312. goto exitStartDevice;
  1313. }
  1314. fullResourceList = ResourceList->List;
  1315. for (i = 0; i < ResourceList->Count; i++) {
  1316. partialResourceList = &(fullResourceList->PartialResourceList);
  1317. partialDescriptors = fullResourceList->PartialResourceList.PartialDescriptors;
  1318. for (j = 0; j < partialResourceList->Count; j++) {
  1319. if (partialDescriptors[j].Type == CmResourceTypeMemory) {
  1320. //Get handle here
  1321. int deviceIndex = 0;
  1322. long baseAddress = partialDescriptors[j].u.Memory.Start.LowPart;
  1323. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Memory %Xh Size %Xh Interf %Xh Bus %Xh\n",
  1324. partialDescriptors[j].u.Memory.Start.LowPart,
  1325. partialDescriptors[j].u.Memory.Length,
  1326. fullResourceList->InterfaceType,
  1327. fullResourceList->BusNumber));
  1328. status = TrueffsCheckDiskOnChip(
  1329. fullResourceList->InterfaceType,
  1330. fullResourceList->BusNumber,
  1331. partialDescriptors[j].u.Memory.Start.LowPart,
  1332. partialDescriptors[j].u.Memory.Length,
  1333. &mappedWindowBase,
  1334. &addressSpace
  1335. );
  1336. if (NT_SUCCESS(status)) {
  1337. for(deviceIndex = 0; deviceIndex < DOC_DRIVES; deviceIndex++) {
  1338. //If Main partition exists
  1339. if(info[deviceIndex].baseAddress == baseAddress){
  1340. deviceExtension->UnitNumber = deviceIndex + (info[deviceIndex].nextPartition << 4);
  1341. info[deviceIndex].nextPartition++;
  1342. break;
  1343. }
  1344. //In case of Main partition doesn't exist
  1345. else if((info[deviceIndex].baseAddress == 0) && (baseAddress != 0)){
  1346. info[deviceIndex].baseAddress = baseAddress;
  1347. deviceExtension->UnitNumber = deviceIndex;
  1348. info[deviceIndex].nextPartition++;
  1349. break;
  1350. }
  1351. }
  1352. if(deviceIndex == DOC_DRIVES){
  1353. goto pcmciaResources;
  1354. }
  1355. }
  1356. if (NT_SUCCESS(status)) {
  1357. deviceExtension->pcmciaParams.windowBase = mappedWindowBase;
  1358. deviceExtension->pcmciaParams.windowSize = partialDescriptors[j].u.Memory.Length;
  1359. deviceExtension->pcmciaParams.addressSpace = addressSpace;
  1360. deviceExtension->pcmciaParams.phWindowBase = RtlConvertLongToLargeInteger(partialDescriptors[j].u.Memory.Start.LowPart);
  1361. deviceExtension->pcmciaParams.physWindow = partialDescriptors[j].u.Memory.Start.QuadPart;
  1362. deviceExtension->pcmciaParams.InterfaceType = fullResourceList->InterfaceType;
  1363. deviceExtension->pcmciaParams.BusNumber = fullResourceList->BusNumber;
  1364. //In case of Main partition
  1365. if((deviceExtension->UnitNumber & 0xf0) == 0)
  1366. updateDocSocketParams(deviceExtension);
  1367. goto goodResources;
  1368. }
  1369. }
  1370. }
  1371. fullResourceList = (PCM_FULL_RESOURCE_DESCRIPTOR) (partialDescriptors + partialResourceList->Count);
  1372. }
  1373. pcmciaResources:
  1374. // DiskOnChip was not found, assume this is PCMCIA
  1375. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  1376. for (i = DOC_DRIVES; i < SOCKETS; i++) {
  1377. if (driveInfo[i].fdoExtension == NULL) {
  1378. deviceExtension->UnitNumber = i;
  1379. break;
  1380. }
  1381. }
  1382. }
  1383. fullResourceList = ResourceList->List;
  1384. for (i = 0; i < ResourceList->Count; i++) {
  1385. partialResourceList = &(fullResourceList->PartialResourceList);
  1386. partialDescriptors = fullResourceList->PartialResourceList.PartialDescriptors;
  1387. for (j = 0; j < partialResourceList->Count; j++) {
  1388. if (partialDescriptors[j].Type == CmResourceTypeMemory) {
  1389. PHYSICAL_ADDRESS AddressMemoryBase;
  1390. ULONG PcmciaAddressSpace = TFFS_MEMORY_SPACE;
  1391. deviceExtension->pcmciaParams.windowSize = partialDescriptors[j].u.Memory.Length;
  1392. deviceExtension->pcmciaParams.phWindowBase = RtlConvertLongToLargeInteger(partialDescriptors[j].u.Memory.Start.LowPart);
  1393. deviceExtension->pcmciaParams.physWindow = partialDescriptors[j].u.Memory.Start.QuadPart;
  1394. deviceExtension->pcmciaParams.InterfaceType = fullResourceList->InterfaceType;
  1395. deviceExtension->pcmciaParams.BusNumber = fullResourceList->BusNumber;
  1396. mappedWindowBase = NULL;
  1397. status = TrueffsTranslateAddress(
  1398. deviceExtension->pcmciaParams.InterfaceType,
  1399. deviceExtension->pcmciaParams.BusNumber,
  1400. deviceExtension->pcmciaParams.phWindowBase,
  1401. deviceExtension->pcmciaParams.windowSize,
  1402. &PcmciaAddressSpace,
  1403. &mappedWindowBase,
  1404. &AddressMemoryBase);
  1405. deviceExtension->pcmciaParams.windowBase = mappedWindowBase;
  1406. deviceExtension->pcmciaParams.addressSpace = PcmciaAddressSpace;
  1407. if (!NT_SUCCESS(status)) {
  1408. goto exitStartDevice;
  1409. }
  1410. status = updatePcmciaSocketParams(deviceExtension);
  1411. if (NT_SUCCESS(status)) {
  1412. goto goodResources;
  1413. }
  1414. }
  1415. }
  1416. fullResourceList = (PCM_FULL_RESOURCE_DESCRIPTOR) (partialDescriptors + partialResourceList->Count);
  1417. }
  1418. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartDevice: pnp manager gave me bad resources!\n"));
  1419. status = STATUS_INVALID_PARAMETER;
  1420. goto exitStartDevice;
  1421. }
  1422. goodResources:
  1423. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Window at %Xh\n",mappedWindowBase));
  1424. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  1425. // Create legacy object names
  1426. status = TrueffsCreateSymblicLinks(deviceExtension);
  1427. if (!NT_SUCCESS(status)) {
  1428. goto exitStartDevice;
  1429. }
  1430. }
  1431. ExReleaseFastMutex(&driveInfoReferenceMutex);
  1432. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartDevice OK\n"));
  1433. return STATUS_SUCCESS;
  1434. exitStartDevice:
  1435. if (!NT_SUCCESS(status)) {
  1436. TrueffsStopRemoveDevice(deviceExtension);
  1437. TrueffsDeleteSymblicLinks(deviceExtension);
  1438. }
  1439. ExReleaseFastMutex(&driveInfoReferenceMutex);
  1440. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartDevice: exit with status %Xh\n",status));
  1441. return status;
  1442. }
  1443. NTSTATUS
  1444. TrueffsMountMedia(
  1445. IN PDEVICE_EXTENSION deviceExtension
  1446. )
  1447. /*++
  1448. Routine Description:
  1449. This is a part of START_DEVICE, called when we get an IPR_MN_START_DEVICE.
  1450. Arguments:
  1451. DeviceObject
  1452. Return Value:
  1453. NTSTATUS
  1454. --*/
  1455. {
  1456. NTSTATUS status;
  1457. FLStatus flStatus = flOK;
  1458. FLStatus flStatusProt = flOK;
  1459. IOreq ioreq;
  1460. IOreq ioreqProt;
  1461. HANDLE threadHandle;
  1462. ULONG heads, sectors, cylinders;
  1463. ULONG prevValue;
  1464. UCHAR currSockets = 0;
  1465. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MountMedia\n"));
  1466. ioreq.irHandle = deviceExtension->UnitNumber;
  1467. flStatus = flAbsMountVolume(&ioreq);
  1468. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MountMedia: flMountVolume returned status %Xh\n",flStatus));
  1469. if (flStatus != flOK) {
  1470. status = STATUS_UNRECOGNIZED_MEDIA;
  1471. goto exitMountMedia;
  1472. }
  1473. //Identify Write Protected Disk
  1474. ioreqProt.irHandle = ioreq.irHandle;
  1475. ioreqProt.irFlags = 0;
  1476. flStatusProt = flIdentifyProtection(&ioreqProt);
  1477. if(flStatusProt == flOK){
  1478. if(ioreqProt.irFlags& WRITE_PROTECTED){
  1479. deviceExtension->IsWriteProtected = TRUE;
  1480. deviceExtension->IsPartitonTableWritten = FALSE;
  1481. RtlZeroMemory (deviceExtension->PartitonTable, sizeof(deviceExtension->PartitonTable));
  1482. }
  1483. else{
  1484. deviceExtension->IsWriteProtected = FALSE;
  1485. deviceExtension->IsPartitonTableWritten = FALSE;
  1486. }
  1487. }
  1488. else{
  1489. deviceExtension->IsWriteProtected = FALSE;
  1490. deviceExtension->IsPartitonTableWritten = FALSE;
  1491. }
  1492. //Identify SW Write Protected Disk
  1493. deviceExtension->IsSWWriteProtected = FALSE;
  1494. /* flStatusProt = flIdentifySWProtection(&ioreqProt);
  1495. if(flStatusProt == flOK){
  1496. if(ioreqProt.irFlags& WRITE_PROTECTED){
  1497. deviceExtension->IsSWWriteProtected = TRUE;
  1498. }
  1499. else{
  1500. deviceExtension->IsSWWriteProtected = FALSE;
  1501. }
  1502. }
  1503. else{
  1504. deviceExtension->IsSWWriteProtected = FALSE;
  1505. }
  1506. */
  1507. //In case of protection allocate Partiton table
  1508. flSectorsInVolume(&ioreq);
  1509. deviceExtension->totalSectors = ioreq.irLength;
  1510. deviceExtension->BytesPerSector = SECTOR_SIZE;
  1511. flBuildGeometry(deviceExtension->totalSectors, &cylinders, &heads, &sectors,0);
  1512. deviceExtension->SectorsPerTrack = sectors;
  1513. deviceExtension->NumberOfHeads = heads;
  1514. deviceExtension->Cylinders = cylinders;
  1515. deviceExtension->totalSectors = deviceExtension->SectorsPerTrack *
  1516. deviceExtension->NumberOfHeads *
  1517. deviceExtension->Cylinders;
  1518. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: internal geometry #sectors %x, #heads %x, #cylinders %x #total %x\n",
  1519. deviceExtension->SectorsPerTrack,
  1520. deviceExtension->NumberOfHeads,
  1521. deviceExtension->Cylinders,
  1522. deviceExtension->totalSectors));
  1523. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)) {
  1524. if (AllocatePdo(deviceExtension) == NULL) {
  1525. status = STATUS_INSUFFICIENT_RESOURCES;
  1526. goto exitMountMedia;
  1527. }
  1528. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Created PDO %Xh\n",deviceExtension->ChildPdo));
  1529. if (++(deviceExtension->threadReferenceCount) == 0) {
  1530. deviceExtension->threadReferenceCount++;
  1531. // Create the thread
  1532. status = PsCreateSystemThread(&threadHandle,
  1533. (ACCESS_MASK) 0L,
  1534. NULL,
  1535. (HANDLE) 0L,
  1536. NULL,
  1537. TrueffsThread,
  1538. deviceExtension);
  1539. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PsCreateSystemThread returned status %Xh\n", status));
  1540. if (!NT_SUCCESS(status)) {
  1541. deviceExtension->threadReferenceCount = -1;
  1542. goto exitMountMedia;
  1543. }
  1544. else {
  1545. status = ObReferenceObjectByHandle( threadHandle,
  1546. SYNCHRONIZE,
  1547. NULL,
  1548. KernelMode,
  1549. &deviceExtension->TffsportThreadObject,
  1550. NULL );
  1551. ASSERT(NT_SUCCESS(status));
  1552. // Not needed.. we have the TffsportThreadObject
  1553. // deviceExtension->DeviceFlags |= DEVICE_FLAG_THREAD;
  1554. }
  1555. ZwClose(threadHandle);
  1556. }
  1557. }
  1558. #ifdef ENVIRONMENT_VARS
  1559. for ( currSockets = 0; currSockets < SOCKETS; currSockets++) {
  1560. if (VerifyWriteState[currSockets])
  1561. status = flSetEnvSocket(FL_VERIFY_WRITE_BDTL,currSockets,VerifyWriteState[currSockets],&prevValue);
  1562. }
  1563. #endif /*ENVIRONMENT_VARS */
  1564. return STATUS_SUCCESS;
  1565. exitMountMedia:
  1566. if (!NT_SUCCESS(status)) {
  1567. TrueffsStopRemoveDevice(deviceExtension);
  1568. TrueffsDeleteSymblicLinks(deviceExtension);
  1569. }
  1570. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MountMedia: exit with status %Xh\n",status));
  1571. return status;
  1572. }
  1573. UCHAR
  1574. TrueffsGetInfoNumber
  1575. (
  1576. PDEVICE_EXTENSION deviceExtension
  1577. )
  1578. {
  1579. UCHAR unitNumber;
  1580. UCHAR i = 0;
  1581. for(; i < (UCHAR)DOC_DRIVES;i++){
  1582. if(info[i].baseAddress == (long)deviceExtension->pcmciaParams.phWindowBase.LowPart)
  1583. break;
  1584. }
  1585. return i;
  1586. }
  1587. NTSTATUS
  1588. TrueffsStopRemoveDevice(
  1589. PDEVICE_EXTENSION deviceExtension
  1590. )
  1591. {
  1592. IOreq ioreq;
  1593. UCHAR deviceIndex;
  1594. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StopRemoveDevice: removed deviceExtension->UnitNumber = %0x\n", deviceExtension->UnitNumber));
  1595. if (deviceExtension->pcmciaParams.windowBase == NULL &&
  1596. deviceExtension->pcmciaParams.physWindow == 0 &&
  1597. driveInfo[deviceExtension->UnitNumber].fdoExtension == NULL) {
  1598. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StopRemoveDevice: Device was already stopped or removed\n"));
  1599. return STATUS_SUCCESS;
  1600. }
  1601. ioreq.irHandle = deviceExtension->UnitNumber;
  1602. flDismountVolume(&ioreq);
  1603. deviceIndex = TrueffsGetInfoNumber(deviceExtension);
  1604. //In case of DiskOnChip (especially MDOCP)
  1605. if( deviceIndex < DOC_DRIVES){
  1606. /* TrueffsFreeTranslatedAddress(deviceExtension->pcmciaParams.windowBase,
  1607. deviceExtension->pcmciaParams.windowSize,
  1608. deviceExtension->pcmciaParams.addressSpace
  1609. );
  1610. */
  1611. deviceExtension->pcmciaParams.windowBase = NULL;
  1612. deviceExtension->pcmciaParams.physWindow = 0;
  1613. //In case of MainPartition
  1614. if((deviceExtension->UnitNumber & 0xf0) == 0){
  1615. driveInfo[deviceExtension->UnitNumber].fdoExtension = NULL;
  1616. driveInfo[deviceExtension->UnitNumber].interfAlive = 0;
  1617. info[deviceIndex].baseAddress = 0;
  1618. }
  1619. info[deviceIndex].nextPartition = (unsigned char)(((deviceExtension->UnitNumber & 0xf0) )>>4);
  1620. // info[deviceIndex].nextPartition--;
  1621. }
  1622. //PCMCIA
  1623. else{
  1624. TrueffsFreeTranslatedAddress(deviceExtension->pcmciaParams.windowBase,
  1625. deviceExtension->pcmciaParams.windowSize,
  1626. deviceExtension->pcmciaParams.addressSpace
  1627. );
  1628. deviceExtension->pcmciaParams.windowBase = NULL;
  1629. deviceExtension->pcmciaParams.physWindow = 0;
  1630. driveInfo[deviceExtension->UnitNumber].fdoExtension = NULL;
  1631. driveInfo[deviceExtension->UnitNumber].interfAlive = 0;
  1632. }
  1633. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: RemoveDevice\n"));
  1634. return STATUS_SUCCESS;
  1635. }
  1636. NTSTATUS
  1637. TrueffsCreateSymblicLinks (
  1638. PDEVICE_EXTENSION FdoExtension
  1639. )
  1640. {
  1641. NTSTATUS status;
  1642. ULONG i;
  1643. PULONG scsiportNumber;
  1644. STRING deviceName;
  1645. CCHAR deviceNameBuffer[64];
  1646. WCHAR deviceSymbolicNameBuffer[64];
  1647. UNICODE_STRING unicodeDeviceNameString;
  1648. UNICODE_STRING unicodeDeviceSymbolicNameString;
  1649. UNICODE_STRING unicodeDeviceArcNameString;
  1650. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CreateSymblicLinks\n"));
  1651. sprintf(deviceNameBuffer, "\\Device\\TffsPort%d", FdoExtension->TrueffsDeviceNumber);
  1652. RtlInitString(&deviceName, deviceNameBuffer);
  1653. status = RtlAnsiStringToUnicodeString(&unicodeDeviceNameString,
  1654. &deviceName,
  1655. TRUE);
  1656. if (!NT_SUCCESS (status)) {
  1657. return status;
  1658. }
  1659. scsiportNumber = &IoGetConfigurationInformation()->ScsiPortCount;
  1660. unicodeDeviceSymbolicNameString.Length = 0;
  1661. unicodeDeviceSymbolicNameString.MaximumLength = 64 * sizeof(WCHAR);
  1662. unicodeDeviceSymbolicNameString.Buffer = deviceSymbolicNameBuffer;
  1663. for (i=0; i <= (*scsiportNumber); i++) {
  1664. sprintf(deviceNameBuffer, "\\Device\\ScsiPort%d", i);
  1665. RtlInitString(&deviceName, deviceNameBuffer);
  1666. status = RtlAnsiStringToUnicodeString(&unicodeDeviceSymbolicNameString,
  1667. &deviceName,
  1668. FALSE);
  1669. if (!NT_SUCCESS (status)) {
  1670. break;
  1671. }
  1672. status = IoCreateSymbolicLink(
  1673. &unicodeDeviceSymbolicNameString,
  1674. &unicodeDeviceNameString
  1675. );
  1676. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IoCreateSymbolicLink returned status %Xh\n",status));
  1677. if (NT_SUCCESS (status)) {
  1678. sprintf(deviceNameBuffer, "\\DosDevices\\Scsi%d:", i);
  1679. RtlInitString(&deviceName, deviceNameBuffer);
  1680. status = RtlAnsiStringToUnicodeString(&unicodeDeviceArcNameString,
  1681. &deviceName,
  1682. TRUE);
  1683. if (!NT_SUCCESS (status)) {
  1684. break;
  1685. }
  1686. IoAssignArcName (
  1687. &unicodeDeviceArcNameString,
  1688. &unicodeDeviceNameString
  1689. );
  1690. RtlFreeUnicodeString (&unicodeDeviceArcNameString);
  1691. break;
  1692. }
  1693. }
  1694. if (NT_SUCCESS(status)) {
  1695. FdoExtension->SymbolicLinkCreated = TRUE;
  1696. FdoExtension->ScsiPortNumber = i;
  1697. (*scsiportNumber)++;
  1698. }
  1699. RtlFreeUnicodeString (&unicodeDeviceNameString);
  1700. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CreateSymblicLinks exit with status %Xh\n",status));
  1701. return status;
  1702. }
  1703. NTSTATUS
  1704. TrueffsDeleteSymblicLinks (
  1705. PDEVICE_EXTENSION FdoExtension
  1706. )
  1707. {
  1708. NTSTATUS status;
  1709. ULONG i;
  1710. STRING deviceName;
  1711. CCHAR deviceNameBuffer[64];
  1712. UNICODE_STRING unicodeDeviceSymbolicNameString;
  1713. UNICODE_STRING unicodeDeviceArcNameString;
  1714. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeleteSymblicLinks\n"));
  1715. if (!FdoExtension->SymbolicLinkCreated) {
  1716. return STATUS_SUCCESS;
  1717. }
  1718. sprintf(deviceNameBuffer, "\\Device\\ScsiPort%d", FdoExtension->ScsiPortNumber);
  1719. RtlInitString(&deviceName, deviceNameBuffer);
  1720. status = RtlAnsiStringToUnicodeString(&unicodeDeviceSymbolicNameString,
  1721. &deviceName,
  1722. TRUE);
  1723. if (NT_SUCCESS (status)) {
  1724. sprintf(deviceNameBuffer, "\\DosDevices\\Scsi%d:", FdoExtension->ScsiPortNumber);
  1725. RtlInitString(&deviceName, deviceNameBuffer);
  1726. status = RtlAnsiStringToUnicodeString(&unicodeDeviceArcNameString,
  1727. &deviceName,
  1728. TRUE);
  1729. if (NT_SUCCESS (status)) {
  1730. status = IoDeleteSymbolicLink(
  1731. &unicodeDeviceSymbolicNameString
  1732. );
  1733. if (NT_SUCCESS (status)) {
  1734. IoDeassignArcName(&unicodeDeviceArcNameString);
  1735. FdoExtension->SymbolicLinkCreated = FALSE;
  1736. IoGetConfigurationInformation()->ScsiPortCount--;
  1737. }
  1738. RtlFreeUnicodeString (&unicodeDeviceArcNameString);
  1739. }
  1740. RtlFreeUnicodeString (&unicodeDeviceSymbolicNameString);
  1741. }
  1742. return status;
  1743. }
  1744. VOID
  1745. TrueffsUnload(
  1746. IN PDRIVER_OBJECT DriverObject
  1747. )
  1748. /*++
  1749. Routine Description:
  1750. Does nothing really...
  1751. Arguments:
  1752. DriverObject - the driver being unloaded
  1753. Return Value:
  1754. none
  1755. --*/
  1756. {
  1757. PTRUEFFSDRIVER_EXTENSION trueffsDriverExtension;
  1758. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Unload\n"));
  1759. flExit();
  1760. trueffsDriverExtension = IoGetDriverObjectExtension(
  1761. DriverObject,
  1762. DRIVER_OBJECT_EXTENSION_ID
  1763. );
  1764. if (trueffsDriverExtension && trueffsDriverExtension->RegistryPath.Buffer != NULL)
  1765. {
  1766. ExFreePool(trueffsDriverExtension->RegistryPath.Buffer);
  1767. }
  1768. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Exitting Unload\n"));
  1769. return;
  1770. }
  1771. NTSTATUS
  1772. TrueffsDeviceControl(
  1773. IN PDEVICE_OBJECT DeviceObject,
  1774. IN PIRP Irp
  1775. )
  1776. /*++
  1777. Routine Description:
  1778. This routine is the device control dispatcher.
  1779. Arguments:
  1780. DeviceObject
  1781. Irp
  1782. Return Value:
  1783. NTSTATUS
  1784. --*/
  1785. {
  1786. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1787. PSTORAGE_PROPERTY_QUERY query;
  1788. //Amir
  1789. PGET_MEDIA_TYPES getMediaTypes;
  1790. NTSTATUS status;
  1791. PDEVICE_EXTENSION deviceExtension;
  1792. PPDO_EXTENSION pdoExtension;
  1793. PDEVICE_EXTENSION_HEADER devExtension;
  1794. BOOLEAN Fdo = FALSE;
  1795. //Amir
  1796. FLStatus tffsStatus;
  1797. IOreq ioreq;
  1798. flIOctlRecord flIoctlRec;
  1799. //End Amir
  1800. devExtension = (PDEVICE_EXTENSION_HEADER) DeviceObject->DeviceExtension;
  1801. if (IS_FDO(devExtension)) {
  1802. deviceExtension = DeviceObject->DeviceExtension;
  1803. Fdo = TRUE;
  1804. }
  1805. else {
  1806. pdoExtension = DeviceObject->DeviceExtension;
  1807. deviceExtension = pdoExtension->Pext;
  1808. }
  1809. Irp->IoStatus.Information = 0;
  1810. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: Code %Xh\n",irpStack->Parameters.DeviceIoControl.IoControlCode));
  1811. switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
  1812. case IOCTL_DISK_GET_DRIVE_GEOMETRY: {
  1813. PDISK_GEOMETRY pDiskGeometry = NULL;
  1814. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: GET_DISK_GEOMETRY\n"));
  1815. // Check size of return buffer
  1816. if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
  1817. sizeof(DISK_GEOMETRY)) {
  1818. status = Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
  1819. Irp->IoStatus.Information = 0;
  1820. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1821. break;
  1822. }
  1823. pDiskGeometry = (PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer;
  1824. // Trueffs is always Fixed Media
  1825. pDiskGeometry->MediaType = FixedMedia;
  1826. // All the fields neccesary are filled in during mount-media
  1827. pDiskGeometry->TracksPerCylinder = deviceExtension->NumberOfHeads;
  1828. pDiskGeometry->SectorsPerTrack = deviceExtension->SectorsPerTrack;
  1829. pDiskGeometry->BytesPerSector = deviceExtension->BytesPerSector;
  1830. pDiskGeometry->Cylinders.QuadPart =
  1831. (LONGLONG)(deviceExtension->totalSectors /
  1832. (pDiskGeometry->TracksPerCylinder * pDiskGeometry->SectorsPerTrack));
  1833. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TracksPerCylinder 0x%x, "
  1834. "SectorsPerTrack 0x%x, BytesPerSector: 0x%x, Cylinders 0x%x\n",
  1835. pDiskGeometry->TracksPerCylinder, pDiskGeometry->SectorsPerTrack,
  1836. pDiskGeometry->BytesPerSector, pDiskGeometry->Cylinders.QuadPart
  1837. ));
  1838. status = Irp->IoStatus.Status = STATUS_SUCCESS;
  1839. Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
  1840. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1841. break;
  1842. }
  1843. //AmirM
  1844. /*case IOCTL_STORAGE_GET_MEDIA_TYPES: {
  1845. PGET_MEDIA_TYPES mediaTypes = Irp->AssociatedIrp.SystemBuffer;
  1846. PDEVICE_MEDIA_INFO mediaInfo = &mediaTypes->MediaInfo[0];
  1847. TffsDebugPrint((TFFS_DEB_INFO,"$$$$$$$$$$$$$IOCTL_STORAGE_GET_MEDIA_TYPES_EX \n"));
  1848. //
  1849. // Ensure that buffer is large enough.
  1850. //
  1851. if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
  1852. sizeof(GET_MEDIA_TYPES)) {
  1853. //
  1854. // Buffer too small.
  1855. //
  1856. Irp->IoStatus.Information = 0;
  1857. status = STATUS_INFO_LENGTH_MISMATCH;
  1858. break;
  1859. }
  1860. mediaTypes->DeviceType = FILE_DEVICE_DISK;
  1861. mediaTypes->MediaInfoCount = 1;
  1862. mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = (LONGLONG)(deviceExtension->totalSectors /
  1863. (deviceExtension->NumberOfHeads * deviceExtension->SectorsPerTrack));
  1864. mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = deviceExtension->NumberOfHeads;
  1865. mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = deviceExtension->SectorsPerTrack;
  1866. mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = deviceExtension->BytesPerSector;
  1867. //
  1868. // Set the type.
  1869. //
  1870. mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = FixedMedia;
  1871. mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
  1872. mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_WRITE_PROTECTED;
  1873. status = Irp->IoStatus.Status = STATUS_SUCCESS;
  1874. Irp->IoStatus.Information = sizeof(GET_MEDIA_TYPES);
  1875. IoCompleteRequest(Irp, 0);
  1876. break;
  1877. }
  1878. */
  1879. case IOCTL_STORAGE_QUERY_PROPERTY: {
  1880. // Validate the query
  1881. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: StorageQueryProperty\n"));
  1882. query = Irp->AssociatedIrp.SystemBuffer;
  1883. if(irpStack->Parameters.DeviceIoControl.InputBufferLength <
  1884. sizeof(STORAGE_PROPERTY_QUERY)) {
  1885. status = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  1886. Irp->IoStatus.Information = 0;
  1887. IoCompleteRequest(Irp, 0);
  1888. break;
  1889. }
  1890. status = TrueffsQueryProperty(deviceExtension, Irp);
  1891. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: QueryProperty returned status %Xh\n", status));
  1892. break;
  1893. }
  1894. case IOCTL_SCSI_GET_DUMP_POINTERS:
  1895. DebugLogEvent(DeviceObject->DriverObject, 300);
  1896. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: ScsiGetDumpPointers\n"));
  1897. if (Fdo) {
  1898. status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  1899. Irp->IoStatus.Information = 0;
  1900. IoCompleteRequest(Irp, 0);
  1901. return status;
  1902. }
  1903. if (Irp->RequestorMode != KernelMode) {
  1904. status = Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  1905. } else if (irpStack->Parameters.DeviceIoControl.OutputBufferLength
  1906. < sizeof(DUMP_POINTERS)) {
  1907. status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
  1908. } else {
  1909. PCRASHDUMP_INIT_DATA dumpInitData;
  1910. dumpInitData = ExAllocatePoolWithTag (NonPagedPool, sizeof (CRASHDUMP_INIT_DATA), TFFSPORT_POOL_TAG);
  1911. if (dumpInitData) {
  1912. PDUMP_POINTERS dumpPointers;
  1913. dumpPointers = (PDUMP_POINTERS)Irp->AssociatedIrp.SystemBuffer;
  1914. RtlZeroMemory (dumpInitData, sizeof (CRASHDUMP_INIT_DATA));
  1915. dumpInitData->cdFdoExtension = pdoExtension->Pext;
  1916. dumpPointers->AdapterObject = NULL;
  1917. dumpPointers->MappedRegisterBase = NULL;
  1918. dumpPointers->DumpData = dumpInitData;
  1919. dumpPointers->CommonBufferVa = NULL;
  1920. dumpPointers->CommonBufferPa.QuadPart = 0;
  1921. dumpPointers->CommonBufferSize = 0;
  1922. dumpPointers->DeviceObject = pdoExtension->DeviceObject;
  1923. dumpPointers->AllocateCommonBuffers = FALSE;
  1924. status = Irp->IoStatus.Status = STATUS_SUCCESS;
  1925. Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
  1926. } else {
  1927. status = Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  1928. }
  1929. }
  1930. IoCompleteRequest(Irp, 0);
  1931. break;
  1932. case IOCTL_TFFSFL_UNIQUE_ID:
  1933. DebugLogEvent(DeviceObject->DriverObject, 200);
  1934. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsGetUniqueId\n"));
  1935. status = QueueIrpToThread(Irp, deviceExtension);
  1936. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: TffsGetUniqueId Completed\n"));
  1937. Irp->IoStatus.Status = status;
  1938. break;
  1939. case IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE:
  1940. DebugLogEvent(DeviceObject->DriverObject, 200);
  1941. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE\n"));
  1942. status = QueueIrpToThread(Irp, deviceExtension);
  1943. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE Completed\n"));
  1944. Irp->IoStatus.Status = status;
  1945. break;
  1946. #ifdef HW_PROTECTION
  1947. case IOCTL_TFFS_BDTL_HW_PROTECTION:
  1948. DebugLogEvent(DeviceObject->DriverObject, 200);
  1949. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_BDTL_HW_PROTECTION\n"));
  1950. status = QueueIrpToThread(Irp, deviceExtension);
  1951. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: IOCTL_TFFS_BDTL_HW_PROTECTION Completed\n"));
  1952. Irp->IoStatus.Status = status;
  1953. break;
  1954. case IOCTL_TFFS_BINARY_HW_PROTECTION:
  1955. DebugLogEvent(DeviceObject->DriverObject, 200);
  1956. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_BINARY_HW_PROTECTION\n"));
  1957. status = QueueIrpToThread(Irp, deviceExtension);
  1958. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: IOCTL_TFFS_BINARY_HW_PROTECTION Completed\n"));
  1959. Irp->IoStatus.Status = status;
  1960. break;
  1961. #endif /*HW_PROTECTION*/
  1962. #ifdef HW_OTP
  1963. case IOCTL_TFFS_OTP:
  1964. DebugLogEvent(DeviceObject->DriverObject, 200);
  1965. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_OTP\n"));
  1966. status = QueueIrpToThread(Irp, deviceExtension);
  1967. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: IOCTL_TFFS_OTP Completed\n"));
  1968. Irp->IoStatus.Status = status;
  1969. break;
  1970. #endif /*HW_OTP*/
  1971. #ifdef WRITE_EXB_IMAGE
  1972. case IOCTL_TFFS_PLACE_EXB_BY_BUFFER:
  1973. DebugLogEvent(DeviceObject->DriverObject, 200);
  1974. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_PLACE_EXB_BY_BUFFER\n"));
  1975. status = QueueIrpToThread(Irp, deviceExtension);
  1976. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: IOCTL_TFFS_PLACE_EXB_BY_BUFFER Completed\n"));
  1977. Irp->IoStatus.Status = status;
  1978. break;
  1979. #endif /*WRITE_EXB_IMAGE*/
  1980. case IOCTL_TFFS_DEEP_POWER_DOWN_MODE:
  1981. DebugLogEvent(DeviceObject->DriverObject, 200);
  1982. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_DEEP_POWER_DOWN_MODE\n"));
  1983. status = QueueIrpToThread(Irp, deviceExtension);
  1984. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: IOCTL_TFFS_DEEP_POWER_DOWN_MODE Completed\n"));
  1985. Irp->IoStatus.Status = status;
  1986. break;
  1987. case IOCTL_TFFSFL_INQUIRE_CAPABILITIES:
  1988. DebugLogEvent(DeviceObject->DriverObject, 200);
  1989. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsGetInquireCapabilities\n"));
  1990. status = QueueIrpToThread(Irp, deviceExtension);
  1991. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: MOTIR: TffsGetInquireCapabilities Completed\n"));
  1992. Irp->IoStatus.Status = status;
  1993. break;
  1994. case IOCTL_TFFS_GET_INFO: // User TFFS IOCTL - FL_GET_INFO
  1995. DebugLogEvent(DeviceObject->DriverObject, 200);
  1996. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsGetInfo\n"));
  1997. status = QueueIrpToThread(Irp, deviceExtension);
  1998. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: TffsGetInfo start get info\n"));
  1999. Irp->IoStatus.Status = status;
  2000. break;
  2001. case IOCTL_TFFS_DEFRAGMENT: // User TFFS IOCTL - FL_DEFRAGMENT
  2002. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsDefragment\n"));
  2003. status = QueueIrpToThread(Irp, deviceExtension);
  2004. Irp->IoStatus.Status = status;
  2005. break;
  2006. #ifdef VERIFY_VOLUME
  2007. case IOCTL_TFFS_VERIFY_VOLUME:
  2008. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsVerifyVolume\n"));
  2009. status = QueueIrpToThread(Irp, deviceExtension);
  2010. Irp->IoStatus.Status = status;
  2011. break;
  2012. #endif VERIFY_VOLUME
  2013. case IOCTL_TFFS_WRITE_PROTECT: // User TFFS IOCTL - FL_WRITE_PROTECT
  2014. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsWriteProtect\n"));
  2015. status = QueueIrpToThread(Irp, deviceExtension);
  2016. Irp->IoStatus.Status = status;
  2017. break;
  2018. case IOCTL_TFFS_MOUNT_VOLUME: // User TFFS IOCTL - FL_MOUNT_VOLUME
  2019. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsMountVolume\n"));
  2020. status = QueueIrpToThread(Irp, deviceExtension);
  2021. Irp->IoStatus.Status = status;
  2022. break;
  2023. case IOCTL_TFFS_FORMAT_VOLUME: // User TFFS IOCTL - FL_FORMAT_VOLUME
  2024. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsFormatVolume\n"));
  2025. status = QueueIrpToThread(Irp, deviceExtension);
  2026. Irp->IoStatus.Status = status;
  2027. break;
  2028. case IOCTL_TFFS_BDK_OPERATION: // User TFFS IOCTL - FL_BDK_OPERATION
  2029. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_BDK_OPERATION\n"));
  2030. status = QueueIrpToThread(Irp, deviceExtension);
  2031. Irp->IoStatus.Status = status;
  2032. break;
  2033. case IOCTL_TFFS_DELETE_SECTORS: // User TFFS IOCTL - FL_DELETE_SECTORS
  2034. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsDeleteSectors\n"));
  2035. status = QueueIrpToThread(Irp, deviceExtension);
  2036. Irp->IoStatus.Status = status;
  2037. break;
  2038. case IOCTL_TFFS_CUSTOMER_ID: // User TFFS IOCTL - FL_IOCTL_NUMBER_OF_PARTITIONS
  2039. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_CUSTOMER_ID\n"));
  2040. status = QueueIrpToThread(Irp, deviceExtension);
  2041. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : start IOCTL_TFFS_CUSTOMER_ID\n"));
  2042. Irp->IoStatus.Status = status;
  2043. break;
  2044. case IOCTL_TFFS_EXTENDED_WRITE_IPL: // User TFFS IOCTL -
  2045. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_EXTENDED_WRITE_IPL\n"));
  2046. status = QueueIrpToThread(Irp, deviceExtension);
  2047. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : start IOCTL_TFFS_EXTENDED_WRITE_IPL\n"));
  2048. Irp->IoStatus.Status = status;
  2049. break;
  2050. #ifdef ENVIRONMENT_VARS
  2051. case IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES: // User TFFS IOCTL -
  2052. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES\n"));
  2053. status = QueueIrpToThread(Irp, deviceExtension);
  2054. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : start IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES\n"));
  2055. Irp->IoStatus.Status = status;
  2056. break;
  2057. #endif /* ENVIRONMENT_VARS */
  2058. case IOCTL_TFFS_NUMBER_OF_PARTITIONS: // User TFFS IOCTL - FL_IOCTL_NUMBER_OF_PARTITIONS
  2059. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: FL_IOCTL_NUMBER_OF_PARTITIONS\n"));
  2060. status = QueueIrpToThread(Irp, deviceExtension);
  2061. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : start FL_IOCTL_NUMBER_OF_PARTITIONS\n"));
  2062. Irp->IoStatus.Status = status;
  2063. break;
  2064. /* case IOCTL_DISK_IS_WRITABLE:
  2065. TffsDebugPrint((TFFS_DEB_ERROR,"#$$%^%$%#%$#%#%$#%#%#%#%#%#%#%$#%#%\n"));
  2066. status = Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
  2067. Irp->IoStatus.Information = 0;
  2068. IoCompleteRequest(Irp, 0);
  2069. break;
  2070. */
  2071. default:
  2072. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: DeviceControl: not suported\n"));
  2073. status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  2074. Irp->IoStatus.Information = 0;
  2075. IoCompleteRequest(Irp, 0);
  2076. break;
  2077. }
  2078. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: exit with status %Xh\n", status));
  2079. return status;
  2080. }
  2081. NTSTATUS
  2082. TrueffsQueryProperty(
  2083. IN PDEVICE_EXTENSION deviceExtension,
  2084. IN PIRP QueryIrp
  2085. )
  2086. /*++
  2087. Routine Description:
  2088. This routine will handle a property query request.
  2089. Arguments:
  2090. DeviceObject - a pointer to the device object being queried
  2091. QueryIrp - a pointer to the irp for the query
  2092. Return Value:
  2093. STATUS_SUCCESS if the query was successful
  2094. other error values as applicable
  2095. --*/
  2096. {
  2097. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(QueryIrp);
  2098. PSTORAGE_PROPERTY_QUERY query = QueryIrp->AssociatedIrp.SystemBuffer;
  2099. STORAGE_DEVICE_DESCRIPTOR deviceDescriptor;
  2100. STORAGE_ADAPTER_DESCRIPTOR adapterDescriptor;
  2101. PSTORAGE_DEVICE_DESCRIPTOR storageDeviceDescriptor;
  2102. ULONG outBufferSize;
  2103. ULONG numBytesToCopy;
  2104. PUCHAR outBuffer;
  2105. PUCHAR outBufferBegin;
  2106. CHAR vendorString[] = VENDORSTRING;
  2107. CHAR productString[] = PRODUCTSTRING;
  2108. CHAR revisionString[] = REVISIONSTRING;
  2109. CHAR serialString[] = SERIALSTRING;
  2110. NTSTATUS status;
  2111. if(query->QueryType >= PropertyMaskQuery) {
  2112. status = STATUS_NOT_IMPLEMENTED;
  2113. QueryIrp->IoStatus.Status = status;
  2114. QueryIrp->IoStatus.Information = 0;
  2115. IoCompleteRequest(QueryIrp, IO_NO_INCREMENT);
  2116. return status;
  2117. }
  2118. if(query->QueryType == PropertyExistsQuery) {
  2119. status = STATUS_SUCCESS;
  2120. QueryIrp->IoStatus.Status = status;
  2121. IoCompleteRequest(QueryIrp, IO_DISK_INCREMENT);
  2122. return status;
  2123. }
  2124. switch(query->PropertyId) {
  2125. case StorageDeviceProperty: {
  2126. outBufferSize = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  2127. RtlZeroMemory (&deviceDescriptor, sizeof(STORAGE_DEVICE_DESCRIPTOR));
  2128. //
  2129. // The buffer needs to be large enough to hold the base
  2130. // structure and all the strings [ null terminated ]
  2131. //
  2132. deviceDescriptor.Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
  2133. deviceDescriptor.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 1 + VENDORSTRINGSIZE + 1 + PRODUCTSTRINGSIZE + 1 + REVISIONSTRINGSIZE + 1 + SERIALSTRINGSIZE + 1;
  2134. deviceDescriptor.DeviceType = deviceExtension->ScsiDeviceType;
  2135. if (deviceExtension->removableMedia)
  2136. {
  2137. deviceDescriptor.RemovableMedia = TRUE;
  2138. }
  2139. deviceDescriptor.BusType = BusTypeAta;
  2140. if (outBufferSize >= deviceDescriptor.Size)
  2141. {
  2142. numBytesToCopy = deviceDescriptor.Size;
  2143. }
  2144. else
  2145. {
  2146. numBytesToCopy = outBufferSize;
  2147. }
  2148. QueryIrp->IoStatus.Information = numBytesToCopy;
  2149. outBuffer = QueryIrp->AssociatedIrp.SystemBuffer;
  2150. outBufferBegin = outBuffer;
  2151. status = STATUS_SUCCESS;
  2152. storageDeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR) QueryIrp->AssociatedIrp.SystemBuffer;
  2153. if (numBytesToCopy > sizeof(STORAGE_DEVICE_DESCRIPTOR))
  2154. {
  2155. RtlCopyMemory (outBuffer, &deviceDescriptor, sizeof(STORAGE_DEVICE_DESCRIPTOR));
  2156. numBytesToCopy -= sizeof(STORAGE_DEVICE_DESCRIPTOR);
  2157. outBuffer += sizeof(STORAGE_DEVICE_DESCRIPTOR);
  2158. }
  2159. else
  2160. {
  2161. RtlCopyMemory (outBuffer, &deviceDescriptor, numBytesToCopy);
  2162. break;
  2163. }
  2164. storageDeviceDescriptor->VendorIdOffset = (ULONG) (outBuffer - outBufferBegin);
  2165. if (numBytesToCopy > VENDORSTRINGSIZE + 1)
  2166. {
  2167. RtlCopyMemory (outBuffer, vendorString, VENDORSTRINGSIZE);
  2168. outBuffer[VENDORSTRINGSIZE] = '\0';
  2169. numBytesToCopy -= VENDORSTRINGSIZE + 1;
  2170. outBuffer += VENDORSTRINGSIZE + 1;
  2171. }
  2172. else
  2173. {
  2174. RtlCopyMemory (outBuffer, vendorString, numBytesToCopy);
  2175. break;
  2176. }
  2177. storageDeviceDescriptor->ProductIdOffset = (ULONG) (outBuffer - outBufferBegin);
  2178. if (numBytesToCopy > PRODUCTSTRINGSIZE + 1)
  2179. {
  2180. RtlCopyMemory (outBuffer, productString, PRODUCTSTRINGSIZE);
  2181. outBuffer[PRODUCTSTRINGSIZE] = '\0';
  2182. numBytesToCopy -= PRODUCTSTRINGSIZE + 1;
  2183. outBuffer += PRODUCTSTRINGSIZE + 1;
  2184. }
  2185. else
  2186. {
  2187. RtlCopyMemory (outBuffer, productString, numBytesToCopy);
  2188. break;
  2189. }
  2190. storageDeviceDescriptor->ProductRevisionOffset = (ULONG) (outBuffer - outBufferBegin);
  2191. if (numBytesToCopy > REVISIONSTRINGSIZE + 1)
  2192. {
  2193. RtlCopyMemory (outBuffer, revisionString, REVISIONSTRINGSIZE);
  2194. outBuffer[REVISIONSTRINGSIZE] = '\0';
  2195. numBytesToCopy -= REVISIONSTRINGSIZE + 1;
  2196. outBuffer += REVISIONSTRINGSIZE + 1;
  2197. }
  2198. else
  2199. {
  2200. RtlCopyMemory (outBuffer, revisionString, numBytesToCopy);
  2201. break;
  2202. }
  2203. storageDeviceDescriptor->SerialNumberOffset = (ULONG) (outBuffer - outBufferBegin);
  2204. if (numBytesToCopy > SERIALSTRINGSIZE + 1)
  2205. {
  2206. RtlCopyMemory (outBuffer, serialString, SERIALSTRINGSIZE);
  2207. outBuffer[SERIALSTRINGSIZE] = '\0';
  2208. }
  2209. else
  2210. {
  2211. RtlCopyMemory (outBuffer, serialString, numBytesToCopy);
  2212. }
  2213. break;
  2214. }
  2215. case StorageAdapterProperty: {
  2216. RtlZeroMemory (&adapterDescriptor, sizeof(adapterDescriptor));
  2217. adapterDescriptor.Version = sizeof (STORAGE_ADAPTER_DESCRIPTOR);
  2218. adapterDescriptor.Size = sizeof (STORAGE_ADAPTER_DESCRIPTOR);
  2219. adapterDescriptor.MaximumTransferLength = MAX_TRANSFER_SIZE_PER_SRB;
  2220. adapterDescriptor.MaximumPhysicalPages = 0xffffffff;
  2221. adapterDescriptor.AlignmentMask = 0x1;
  2222. adapterDescriptor.AdapterUsesPio = TRUE;
  2223. adapterDescriptor.AdapterScansDown = FALSE;
  2224. adapterDescriptor.CommandQueueing = FALSE;
  2225. adapterDescriptor.AcceleratedTransfer = FALSE;
  2226. adapterDescriptor.BusType = BusTypeAta;
  2227. adapterDescriptor.BusMajorVersion = 1;
  2228. adapterDescriptor.BusMinorVersion = 0;
  2229. if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
  2230. sizeof(STORAGE_ADAPTER_DESCRIPTOR)) {
  2231. outBufferSize = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  2232. } else {
  2233. outBufferSize = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
  2234. }
  2235. RtlCopyMemory (QueryIrp->AssociatedIrp.SystemBuffer,
  2236. &adapterDescriptor,
  2237. outBufferSize);
  2238. QueryIrp->IoStatus.Information = outBufferSize;
  2239. status = STATUS_SUCCESS;
  2240. break;
  2241. }
  2242. default: {
  2243. status = STATUS_NOT_IMPLEMENTED;
  2244. QueryIrp->IoStatus.Information = 0;
  2245. break;
  2246. }
  2247. }
  2248. QueryIrp->IoStatus.Status = status;
  2249. IoCompleteRequest(QueryIrp, IO_DISK_INCREMENT);
  2250. return status;
  2251. }
  2252. NTSTATUS
  2253. TrueffsCreateClose(
  2254. IN PDEVICE_OBJECT DeviceObject,
  2255. IN PIRP Irp
  2256. )
  2257. /*++
  2258. Routine Description:
  2259. create and close routine. This is called by the I/O system
  2260. when the device is opened or closed.
  2261. Arguments:
  2262. DeviceObject - Pointer to device object
  2263. Irp - IRP involved.
  2264. Return Value:
  2265. STATUS_SUCCESS.
  2266. --*/
  2267. {
  2268. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: CreateClose\n"));
  2269. Irp->IoStatus.Status = STATUS_SUCCESS;
  2270. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2271. return STATUS_SUCCESS;
  2272. }
  2273. NTSTATUS
  2274. TrueffsPnpDeviceControl(
  2275. PDEVICE_OBJECT DeviceObject,
  2276. PIRP Irp
  2277. )
  2278. {
  2279. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  2280. PDEVICE_EXTENSION deviceExtension;
  2281. PPDO_EXTENSION pdoExtension = NULL;
  2282. PDEVICE_EXTENSION_HEADER devExtension;
  2283. NTSTATUS status;
  2284. KIRQL cIrql;
  2285. KEVENT event;
  2286. BOOLEAN Fdo = FALSE;
  2287. BOOLEAN processHeldRequests = FALSE;
  2288. devExtension = (PDEVICE_EXTENSION_HEADER) DeviceObject->DeviceExtension;
  2289. if (IS_FDO(devExtension))
  2290. {
  2291. deviceExtension = DeviceObject->DeviceExtension;
  2292. Fdo = TRUE;
  2293. }
  2294. else
  2295. {
  2296. pdoExtension = DeviceObject->DeviceExtension;
  2297. deviceExtension = pdoExtension->Pext;
  2298. }
  2299. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: Function %Xh %cDO.\n",irpStack->MinorFunction, Fdo ? 'F':'P'));
  2300. KeInitializeEvent(&event, NotificationEvent, FALSE);
  2301. switch (irpStack->MinorFunction)
  2302. {
  2303. case IRP_MN_START_DEVICE:
  2304. TffsDebugPrint((TFFS_DEB_INFO, "Trueffs: PnpDeviceControl: START_DEVICE\n"));
  2305. if (Fdo)
  2306. {
  2307. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2308. deviceExtension->DeviceFlags |= DEVICE_FLAG_STOPPED;
  2309. if (deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED)
  2310. {
  2311. processHeldRequests = TRUE;
  2312. }
  2313. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2314. status = TrueffsStartDevice(deviceExtension, irpStack->Parameters.StartDevice.AllocatedResourcesTranslated, TRUE);
  2315. if (NT_SUCCESS(status))
  2316. {
  2317. //
  2318. // Forward this request down synchronously, so that the lower drivers can be started
  2319. //
  2320. IoCopyCurrentIrpStackLocationToNext(Irp);
  2321. status = TrueffsCallDriverSync(deviceExtension->LowerDeviceObject, Irp);
  2322. if (NT_SUCCESS(status))
  2323. {
  2324. status = TrueffsMountMedia(deviceExtension);
  2325. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2326. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_STOPPED;
  2327. deviceExtension->DeviceFlags |= DEVICE_FLAG_STARTED;
  2328. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2329. if (processHeldRequests && !KeReadStateSemaphore(&deviceExtension->requestSemaphore))
  2330. {
  2331. KeReleaseSemaphore(&deviceExtension->requestSemaphore, (KPRIORITY) 0, 1, FALSE);
  2332. }
  2333. }
  2334. }
  2335. Irp->IoStatus.Status = status;
  2336. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2337. }
  2338. else
  2339. {
  2340. status = STATUS_SUCCESS;
  2341. if (!pdoExtension->CrashDumpPathCount)
  2342. {
  2343. DEVICE_POWER_STATE devicePowerState = PowerDeviceD3;
  2344. pdoExtension->IdleCounter = PoRegisterDeviceForIdleDetection(pdoExtension->DeviceObject,
  2345. DEVICE_DEFAULT_IDLE_TIMEOUT,
  2346. DEVICE_DEFAULT_IDLE_TIMEOUT,
  2347. devicePowerState);
  2348. }
  2349. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2350. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_CHILD_REMOVED;
  2351. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2352. TrueffsWmiRegister ((PDEVICE_EXTENSION_HEADER)pdoExtension);
  2353. Irp->IoStatus.Status = status;
  2354. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2355. }
  2356. break;
  2357. case IRP_MN_QUERY_STOP_DEVICE:
  2358. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: QUERY_STOP_DEVICE\n"));
  2359. status = STATUS_SUCCESS;
  2360. if (Fdo)
  2361. {
  2362. if (deviceExtension->PagingPathCount || deviceExtension->CrashDumpPathCount)
  2363. {
  2364. status = STATUS_UNSUCCESSFUL;
  2365. }
  2366. }
  2367. else
  2368. {
  2369. if (pdoExtension->PagingPathCount || pdoExtension->CrashDumpPathCount)
  2370. {
  2371. status = STATUS_UNSUCCESSFUL;
  2372. }
  2373. }
  2374. if (!NT_SUCCESS(status))
  2375. {
  2376. Irp->IoStatus.Status = status;
  2377. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2378. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: Failing QUERY_STOP: we are in PagingPath or CrashDumpPath\n"));
  2379. break;
  2380. }
  2381. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2382. deviceExtension->DeviceFlags |= DEVICE_FLAG_QUERY_STOP_REMOVE;
  2383. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2384. if (Fdo)
  2385. {
  2386. if (deviceExtension->TffsportThreadObject)
  2387. {
  2388. KeWaitForSingleObject(&deviceExtension->PendingIRPEvent, Executive, KernelMode, FALSE, NULL);
  2389. }
  2390. IoSkipCurrentIrpStackLocation(Irp);
  2391. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2392. }
  2393. else
  2394. {
  2395. Irp->IoStatus.Status = status;
  2396. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2397. }
  2398. break;
  2399. case IRP_MN_STOP_DEVICE:
  2400. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: STOP_DEVICE\n"));
  2401. status = STATUS_SUCCESS;
  2402. if (Fdo)
  2403. {
  2404. TrueffsStopRemoveDevice(deviceExtension);
  2405. IoSkipCurrentIrpStackLocation(Irp);
  2406. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2407. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2408. deviceExtension->DeviceFlags |= DEVICE_FLAG_STOPPED;
  2409. deviceExtension->DeviceFlags |= DEVICE_FLAG_QUERY_STOP_REMOVE;
  2410. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2411. }
  2412. else
  2413. {
  2414. DEVICE_POWER_STATE devicePowerState = PowerDeviceD3;
  2415. if (pdoExtension->IdleCounter)
  2416. {
  2417. PoRegisterDeviceForIdleDetection(pdoExtension->DeviceObject, 0, 0, devicePowerState);
  2418. pdoExtension->IdleCounter = NULL;
  2419. }
  2420. Irp->IoStatus.Status = status;
  2421. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2422. }
  2423. break;
  2424. case IRP_MN_QUERY_REMOVE_DEVICE:
  2425. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: QUERY_REMOVE_DEVICE\n"));
  2426. status = STATUS_SUCCESS;
  2427. if (Fdo)
  2428. {
  2429. if (deviceExtension->PagingPathCount || deviceExtension->CrashDumpPathCount)
  2430. {
  2431. status = STATUS_UNSUCCESSFUL;
  2432. }
  2433. }
  2434. else
  2435. {
  2436. if (pdoExtension->PagingPathCount || pdoExtension->CrashDumpPathCount)
  2437. {
  2438. status = STATUS_UNSUCCESSFUL;
  2439. }
  2440. }
  2441. if (!NT_SUCCESS(status))
  2442. {
  2443. Irp->IoStatus.Status = status;
  2444. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2445. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: Failing QUERY_REMOVE: we are in PagingPath or CrashDumpPath\n"));
  2446. break;
  2447. }
  2448. //
  2449. // We're not going to queue irps during remove device
  2450. // KLUDGE
  2451. //
  2452. //
  2453. // KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2454. // deviceExtension->DeviceFlags |= DEVICE_FLAG_QUERY_STOP_REMOVE;
  2455. // KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2456. //
  2457. if (Fdo)
  2458. {
  2459. // No need to wait for the thread to become idle
  2460. // KLUDGE
  2461. // if (deviceExtension->DeviceFlags & DEVICE_FLAG_THREAD) {
  2462. // KeWaitForSingleObject(&deviceExtension->PendingIRPEvent,
  2463. // Executive, KernelMode, FALSE, NULL);
  2464. // }
  2465. IoSkipCurrentIrpStackLocation(Irp);
  2466. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2467. }
  2468. else
  2469. {
  2470. Irp->IoStatus.Status = status;
  2471. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2472. }
  2473. break;
  2474. case IRP_MN_CANCEL_STOP_DEVICE:
  2475. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: CANCEL_STOP_DEVICE\n"));
  2476. status = STATUS_SUCCESS;
  2477. if (Fdo)
  2478. {
  2479. IoSkipCurrentIrpStackLocation(Irp);
  2480. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2481. }
  2482. else
  2483. {
  2484. Irp->IoStatus.Status = status;
  2485. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2486. }
  2487. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2488. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_QUERY_STOP_REMOVE;
  2489. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2490. if (!KeReadStateSemaphore(&deviceExtension->requestSemaphore))
  2491. {
  2492. KeReleaseSemaphore(&deviceExtension->requestSemaphore,(KPRIORITY) 0, 1, FALSE);
  2493. }
  2494. break;
  2495. case IRP_MN_CANCEL_REMOVE_DEVICE:
  2496. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: CANCEL_REMOVE_DEVICE\n"));
  2497. status = STATUS_SUCCESS;
  2498. if (Fdo)
  2499. {
  2500. IoSkipCurrentIrpStackLocation(Irp);
  2501. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2502. }
  2503. else
  2504. {
  2505. Irp->IoStatus.Status = status;
  2506. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2507. }
  2508. //
  2509. // This flas was never set by QUERY_REMOVE
  2510. // due to the KLUDGE we added, for not queuing IRPS's during QUERY_REMOVE
  2511. //
  2512. // KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2513. // deviceExtension->DeviceFlags &= ~DEVICE_FLAG_QUERY_STOP_REMOVE;
  2514. // KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2515. if (!KeReadStateSemaphore(&deviceExtension->requestSemaphore))
  2516. {
  2517. KeReleaseSemaphore(&deviceExtension->requestSemaphore,(KPRIORITY) 0, 1, FALSE);
  2518. }
  2519. break;
  2520. case IRP_MN_REMOVE_DEVICE:
  2521. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: REMOVE_DEVICE\n"));
  2522. status = STATUS_SUCCESS;
  2523. if (Fdo)
  2524. {
  2525. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_REMOVED))
  2526. {
  2527. // Set the QUERY_STOP_REMOVE FLAG
  2528. // Part of the KLUDGE, we had removed this from the QUERY_REMOVE IRP
  2529. // processing
  2530. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2531. deviceExtension->DeviceFlags |= DEVICE_FLAG_QUERY_STOP_REMOVE;
  2532. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2533. // Now wait for the thread to complete any work its doing
  2534. // Better wait for the thread to complete the current IRP it may be
  2535. // working on
  2536. //
  2537. // if (deviceExtension->DeviceFlags & DEVICE_FLAG_THREAD) {
  2538. //
  2539. if (deviceExtension->TffsportThreadObject)
  2540. {
  2541. KeWaitForSingleObject(&deviceExtension->PendingIRPEvent, Executive, KernelMode, FALSE, NULL);
  2542. }
  2543. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2544. deviceExtension->DeviceFlags |= DEVICE_FLAG_REMOVED;
  2545. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_QUERY_STOP_REMOVE;
  2546. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_HOLD_IRPS;
  2547. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2548. while (ExInterlockedRemoveHeadList(&deviceExtension->listEntry, &deviceExtension->listSpinLock))
  2549. {
  2550. ;
  2551. }
  2552. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2553. deviceExtension->threadReferenceCount = 0;
  2554. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2555. if (!KeReadStateSemaphore(&deviceExtension->requestSemaphore))
  2556. {
  2557. KeReleaseSemaphore(&deviceExtension->requestSemaphore,(KPRIORITY) 0,1,FALSE);
  2558. }
  2559. //
  2560. // if (deviceExtension->DeviceFlags & DEVICE_FLAG_THREAD) {
  2561. //
  2562. if (deviceExtension->TffsportThreadObject)
  2563. {
  2564. KeWaitForSingleObject(deviceExtension->TffsportThreadObject, Executive, KernelMode, FALSE, NULL);
  2565. ObDereferenceObject(deviceExtension->TffsportThreadObject);
  2566. deviceExtension->TffsportThreadObject = NULL;
  2567. }
  2568. TrueffsStopRemoveDevice(deviceExtension);
  2569. }
  2570. IoSkipCurrentIrpStackLocation(Irp);
  2571. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2572. //
  2573. // Clean up resources here
  2574. //
  2575. if (deviceExtension->ChildPdo != NULL)
  2576. {
  2577. IoDeleteDevice(deviceExtension->ChildPdo);
  2578. }
  2579. TrueffsDeleteSymblicLinks(deviceExtension);
  2580. IoDetachDevice(deviceExtension->LowerDeviceObject);
  2581. IoDeleteDevice(DeviceObject);
  2582. }
  2583. else
  2584. {
  2585. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_CHILD_REMOVED))
  2586. {
  2587. DEVICE_POWER_STATE devicePowerState;
  2588. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2589. deviceExtension->DeviceFlags |= DEVICE_FLAG_CHILD_REMOVED;
  2590. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_QUERY_STOP_REMOVE;
  2591. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_HOLD_IRPS;
  2592. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2593. while (ExInterlockedRemoveHeadList(&deviceExtension->listEntry, &deviceExtension->listSpinLock))
  2594. {
  2595. ;
  2596. }
  2597. devicePowerState = PowerDeviceD3;
  2598. if (pdoExtension->IdleCounter)
  2599. {
  2600. PoRegisterDeviceForIdleDetection(pdoExtension->DeviceObject, 0, 0, devicePowerState);
  2601. pdoExtension->IdleCounter = NULL;
  2602. }
  2603. TrueffsWmiDeregister((PDEVICE_EXTENSION_HEADER)pdoExtension);
  2604. }
  2605. Irp->IoStatus.Status = status;
  2606. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2607. }
  2608. break;
  2609. case IRP_MN_SURPRISE_REMOVAL:
  2610. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: SURPRISE_REMOVAL\n"));
  2611. status = STATUS_SUCCESS;
  2612. if (Fdo)
  2613. {
  2614. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2615. deviceExtension->DeviceFlags |= DEVICE_FLAG_REMOVED;
  2616. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_QUERY_STOP_REMOVE;
  2617. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_HOLD_IRPS;
  2618. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2619. while (ExInterlockedRemoveHeadList(&deviceExtension->listEntry,&deviceExtension->listSpinLock))
  2620. {
  2621. ;
  2622. }
  2623. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2624. deviceExtension->threadReferenceCount = 0;
  2625. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2626. if (!KeReadStateSemaphore(&deviceExtension->requestSemaphore))
  2627. {
  2628. KeReleaseSemaphore(&deviceExtension->requestSemaphore,(KPRIORITY) 0, 1, FALSE);
  2629. }
  2630. //
  2631. // if (deviceExtension->DeviceFlags & DEVICE_FLAG_THREAD) {
  2632. //
  2633. if (deviceExtension->TffsportThreadObject)
  2634. {
  2635. KeWaitForSingleObject(deviceExtension->TffsportThreadObject, Executive, KernelMode, FALSE, NULL);
  2636. ObDereferenceObject(deviceExtension->TffsportThreadObject);
  2637. deviceExtension->TffsportThreadObject = NULL;
  2638. }
  2639. IoSkipCurrentIrpStackLocation(Irp);
  2640. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2641. TrueffsStopRemoveDevice(deviceExtension);
  2642. TrueffsDeleteSymblicLinks(deviceExtension);
  2643. }
  2644. else
  2645. {
  2646. DEVICE_POWER_STATE devicePowerState;
  2647. IoInvalidateDeviceRelations(deviceExtension->MainPdo,BusRelations);
  2648. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  2649. deviceExtension->DeviceFlags |= DEVICE_FLAG_CHILD_REMOVED;
  2650. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  2651. devicePowerState = PowerDeviceD3;
  2652. if (pdoExtension->IdleCounter)
  2653. {
  2654. PoRegisterDeviceForIdleDetection(pdoExtension->DeviceObject, 0, 0, devicePowerState);
  2655. pdoExtension->IdleCounter = NULL;
  2656. }
  2657. TrueffsWmiDeregister((PDEVICE_EXTENSION_HEADER)pdoExtension);
  2658. Irp->IoStatus.Status = status;
  2659. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2660. }
  2661. break;
  2662. case IRP_MN_QUERY_ID:
  2663. status = TrueffsDeviceQueryId(DeviceObject, Irp, Fdo);
  2664. break;
  2665. case IRP_MN_QUERY_DEVICE_RELATIONS:
  2666. status = TrueffsQueryDeviceRelations(DeviceObject, Irp, Fdo);
  2667. break;
  2668. case IRP_MN_QUERY_CAPABILITIES:
  2669. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: QUERY_CAPABILITIES\n"));
  2670. if (Fdo)
  2671. {
  2672. IoSkipCurrentIrpStackLocation(Irp);
  2673. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2674. }
  2675. else
  2676. {
  2677. status = TrueffsDeviceQueryCapabilities(deviceExtension, irpStack->Parameters.DeviceCapabilities.Capabilities);
  2678. Irp->IoStatus.Status = status;
  2679. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2680. }
  2681. break;
  2682. case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  2683. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl: DEVICE_USAGE_NOTIFICATION, Type %Xh\n", irpStack->Parameters.UsageNotification.Type));
  2684. if (Fdo)
  2685. {
  2686. PULONG deviceUsageCount = NULL;
  2687. if (!(deviceExtension->DeviceFlags & DEVICE_FLAG_STARTED))
  2688. {
  2689. status = STATUS_DEVICE_NOT_READY;
  2690. Irp->IoStatus.Status = status;
  2691. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2692. break;
  2693. }
  2694. switch (irpStack->Parameters.UsageNotification.Type)
  2695. {
  2696. case DeviceUsageTypePaging:
  2697. deviceUsageCount = &deviceExtension->PagingPathCount;
  2698. break;
  2699. case DeviceUsageTypeHibernation:
  2700. deviceUsageCount = &deviceExtension->HiberPathCount;
  2701. break;
  2702. case DeviceUsageTypeDumpFile:
  2703. deviceUsageCount = &deviceExtension->CrashDumpPathCount;
  2704. break;
  2705. default:
  2706. deviceUsageCount = NULL;
  2707. break;
  2708. }
  2709. //
  2710. // Forward this request down synchronously, in case a lower driver wants to veto it
  2711. //
  2712. IoCopyCurrentIrpStackLocationToNext(Irp);
  2713. status = TrueffsCallDriverSync(deviceExtension->LowerDeviceObject, Irp);
  2714. if (NT_SUCCESS(status))
  2715. {
  2716. if (deviceUsageCount)
  2717. {
  2718. IoAdjustPagingPathCount(deviceUsageCount, irpStack->Parameters.UsageNotification.InPath);
  2719. }
  2720. }
  2721. Irp->IoStatus.Status = status;
  2722. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2723. }
  2724. else
  2725. {
  2726. PULONG deviceUsageCount = NULL;
  2727. if (pdoExtension)
  2728. {
  2729. PDEVICE_OBJECT targetDeviceObject;
  2730. IO_STATUS_BLOCK ioStatus = { 0 };
  2731. switch (irpStack->Parameters.UsageNotification.Type)
  2732. {
  2733. case DeviceUsageTypePaging:
  2734. deviceUsageCount = &pdoExtension->PagingPathCount;
  2735. break;
  2736. case DeviceUsageTypeHibernation:
  2737. deviceUsageCount = &pdoExtension->HiberPathCount;
  2738. break;
  2739. case DeviceUsageTypeDumpFile:
  2740. deviceUsageCount = &pdoExtension->CrashDumpPathCount;
  2741. break;
  2742. default:
  2743. deviceUsageCount = NULL;
  2744. break;
  2745. }
  2746. targetDeviceObject = IoGetAttachedDeviceReference(deviceExtension->DeviceObject);
  2747. ioStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  2748. status = TrueffsSyncSendIrp(targetDeviceObject, irpStack, &ioStatus);
  2749. ObDereferenceObject(targetDeviceObject);
  2750. if (NT_SUCCESS(status))
  2751. {
  2752. if (deviceUsageCount)
  2753. {
  2754. IoAdjustPagingPathCount(deviceUsageCount, irpStack->Parameters.UsageNotification.InPath);
  2755. }
  2756. if (irpStack->Parameters.UsageNotification.Type == DeviceUsageTypeDumpFile)
  2757. {
  2758. POWER_STATE powerState;
  2759. DEVICE_POWER_STATE devicePowerState = PowerDeviceD3;
  2760. //
  2761. // Reset the idle timeout to "forever"
  2762. //
  2763. pdoExtension->IdleCounter = PoRegisterDeviceForIdleDetection(pdoExtension->DeviceObject,
  2764. DEVICE_VERY_LONG_IDLE_TIMEOUT,
  2765. DEVICE_VERY_LONG_IDLE_TIMEOUT,
  2766. devicePowerState);
  2767. if (pdoExtension->IdleCounter)
  2768. {
  2769. PoSetDeviceBusy(pdoExtension->IdleCounter);
  2770. }
  2771. powerState.DeviceState = PowerDeviceD0;
  2772. PoRequestPowerIrp(pdoExtension->DeviceObject, IRP_MN_SET_POWER, powerState, NULL, NULL, NULL);
  2773. }
  2774. }
  2775. }
  2776. else
  2777. {
  2778. status = STATUS_NO_SUCH_DEVICE;
  2779. }
  2780. Irp->IoStatus.Status = status;
  2781. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2782. }
  2783. break;
  2784. default:
  2785. if (Fdo)
  2786. {
  2787. //
  2788. // Forward this request down, in case a lower driver understands it
  2789. //
  2790. IoSkipCurrentIrpStackLocation(Irp);
  2791. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2792. }
  2793. else
  2794. {
  2795. //
  2796. // Complete this request without altering its status
  2797. //
  2798. status = Irp->IoStatus.Status;
  2799. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2800. }
  2801. break;
  2802. }
  2803. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PnpDeviceControl status %Xh\n", status));
  2804. return status;
  2805. }
  2806. NTSTATUS
  2807. TrueffsSyncSendIrp (
  2808. IN PDEVICE_OBJECT TargetDeviceObject,
  2809. IN PIO_STACK_LOCATION IrpSp,
  2810. IN OUT OPTIONAL PIO_STATUS_BLOCK IoStatus
  2811. )
  2812. {
  2813. PIO_STACK_LOCATION newIrpSp;
  2814. PIRP newIrp;
  2815. KEVENT event;
  2816. NTSTATUS status;
  2817. newIrp = IoAllocateIrp (TargetDeviceObject->StackSize, FALSE);
  2818. if (newIrp == NULL) {
  2819. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: SyncSendIrp: Unable to allocate an irp\n"));
  2820. return STATUS_NO_MEMORY;
  2821. }
  2822. newIrpSp = IoGetNextIrpStackLocation(newIrp);
  2823. RtlMoveMemory (newIrpSp, IrpSp, sizeof (*IrpSp));
  2824. if (IoStatus) {
  2825. newIrp->IoStatus.Status = IoStatus->Status;
  2826. } else {
  2827. newIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  2828. }
  2829. KeInitializeEvent(&event, NotificationEvent, FALSE);
  2830. IoSetCompletionRoutine (
  2831. newIrp,
  2832. TrueffsSyncSendIrpCompletionRoutine,
  2833. &event,
  2834. TRUE,
  2835. TRUE,
  2836. TRUE);
  2837. status = IoCallDriver (TargetDeviceObject, newIrp);
  2838. if (status == STATUS_PENDING) {
  2839. status = KeWaitForSingleObject(&event,
  2840. Executive,
  2841. KernelMode,
  2842. FALSE,
  2843. NULL);
  2844. }
  2845. status = newIrp->IoStatus.Status;
  2846. if (IoStatus) {
  2847. *IoStatus = newIrp->IoStatus;
  2848. }
  2849. IoFreeIrp (newIrp);
  2850. return status;
  2851. }
  2852. NTSTATUS
  2853. TrueffsSyncSendIrpCompletionRoutine (
  2854. IN PDEVICE_OBJECT DeviceObject,
  2855. IN PIRP Irp,
  2856. IN PVOID Context
  2857. )
  2858. {
  2859. PKEVENT event = Context;
  2860. KeSetEvent(event, EVENT_INCREMENT,FALSE);
  2861. return STATUS_MORE_PROCESSING_REQUIRED;
  2862. }
  2863. NTSTATUS
  2864. TrueffsCallDriverSync(
  2865. IN PDEVICE_OBJECT DeviceObject,
  2866. IN OUT PIRP Irp
  2867. )
  2868. {
  2869. KEVENT event;
  2870. NTSTATUS status;
  2871. PAGED_CODE();
  2872. KeInitializeEvent(&event, NotificationEvent, FALSE);
  2873. IoSetCompletionRoutine(Irp, TrueffsCallDriverSyncCompletion, &event, TRUE, TRUE, TRUE);
  2874. status = IoCallDriver(DeviceObject, Irp);
  2875. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  2876. status = Irp->IoStatus.Status;
  2877. return status;
  2878. }
  2879. NTSTATUS
  2880. TrueffsCallDriverSyncCompletion(
  2881. IN PDEVICE_OBJECT DeviceObject,
  2882. IN PIRP Irp,
  2883. IN PVOID Context
  2884. )
  2885. {
  2886. PKEVENT event = (PKEVENT)Context;
  2887. ASSERT(Irp->IoStatus.Status != STATUS_IO_TIMEOUT);
  2888. KeSetEvent(event, 0, FALSE);
  2889. return STATUS_MORE_PROCESSING_REQUIRED;
  2890. }
  2891. NTSTATUS
  2892. TrueffsPowerControl(
  2893. PDEVICE_OBJECT DeviceObject,
  2894. PIRP Irp
  2895. )
  2896. {
  2897. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  2898. PDEVICE_EXTENSION deviceExtension;
  2899. PDEVICE_EXTENSION_HEADER devExtension;
  2900. BOOLEAN Fdo = FALSE;
  2901. NTSTATUS status;
  2902. devExtension = (PDEVICE_EXTENSION_HEADER) DeviceObject->DeviceExtension;
  2903. if (IS_FDO(devExtension))
  2904. {
  2905. deviceExtension = DeviceObject->DeviceExtension;
  2906. Fdo = TRUE;
  2907. }
  2908. else
  2909. {
  2910. PPDO_EXTENSION pdoExtension = DeviceObject->DeviceExtension;
  2911. deviceExtension = pdoExtension->Pext;
  2912. }
  2913. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PowerControl: Function %Xh %cDO.\n", irpStack->MinorFunction,Fdo ? 'F':'P'));
  2914. switch (irpStack->MinorFunction)
  2915. {
  2916. case IRP_MN_SET_POWER:
  2917. if (Fdo)
  2918. {
  2919. status = TrueffsSetFdoPowerState(DeviceObject, Irp);
  2920. }
  2921. else
  2922. {
  2923. status = TrueffsSetPdoPowerState(DeviceObject, Irp);
  2924. }
  2925. break;
  2926. case IRP_MN_QUERY_POWER:
  2927. status = STATUS_SUCCESS;
  2928. PoStartNextPowerIrp(Irp);
  2929. if (Fdo)
  2930. {
  2931. IoSkipCurrentIrpStackLocation(Irp);
  2932. status = PoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2933. }
  2934. else
  2935. {
  2936. Irp->IoStatus.Status = status;
  2937. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2938. }
  2939. break;
  2940. default:
  2941. PoStartNextPowerIrp(Irp);
  2942. if (Fdo)
  2943. {
  2944. //
  2945. // Forward this request down, in case a lower driver understands it
  2946. //
  2947. IoSkipCurrentIrpStackLocation(Irp);
  2948. status = PoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  2949. }
  2950. else
  2951. {
  2952. //
  2953. // Complete this request without altering its status
  2954. //
  2955. status = Irp->IoStatus.Status;
  2956. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2957. }
  2958. break;
  2959. }
  2960. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: PowerControl status %Xh\n", status));
  2961. return status;
  2962. }
  2963. NTSTATUS
  2964. TrueffsSetFdoPowerState (
  2965. IN PDEVICE_OBJECT DeviceObject,
  2966. IN OUT PIRP Irp
  2967. )
  2968. /*++
  2969. Routine Description
  2970. Dispatches the IRP based on whether a system power state
  2971. or device power state transition is requested
  2972. Arguments
  2973. DeviceObject - Pointer to the functional device object for the pcmcia controller
  2974. Irp - Pointer to the Irp for the power dispatch
  2975. Return value
  2976. status
  2977. --*/
  2978. {
  2979. PDEVICE_EXTENSION fdoExtension;
  2980. PIO_STACK_LOCATION irpStack;
  2981. NTSTATUS status = STATUS_SUCCESS;
  2982. PFDO_POWER_CONTEXT context = NULL;
  2983. BOOLEAN passItDown;
  2984. fdoExtension = DeviceObject->DeviceExtension;
  2985. context = ExAllocatePoolWithTag (NonPagedPool, sizeof(FDO_POWER_CONTEXT), TFFSPORT_POOL_TAG);
  2986. if (context == NULL) {
  2987. status = STATUS_INSUFFICIENT_RESOURCES;
  2988. } else {
  2989. RtlZeroMemory (context, sizeof(FDO_POWER_CONTEXT));
  2990. irpStack = IoGetCurrentIrpStackLocation (Irp);
  2991. passItDown = TRUE;
  2992. context->PowerType = irpStack->Parameters.Power.Type;
  2993. context->PowerState = irpStack->Parameters.Power.State;
  2994. if (irpStack->Parameters.Power.Type == SystemPowerState) {
  2995. if (fdoExtension->SystemPowerState == irpStack->Parameters.Power.State.SystemState) {
  2996. // We are already in the given state
  2997. passItDown = FALSE;
  2998. }
  2999. } else if (irpStack->Parameters.Power.Type == DevicePowerState) {
  3000. if (fdoExtension->DevicePowerState != irpStack->Parameters.Power.State.DeviceState) {
  3001. if (fdoExtension->DevicePowerState == PowerDeviceD0) {
  3002. // getting out of D0 state, better call PoSetPowerState now
  3003. PoSetPowerState (
  3004. DeviceObject,
  3005. DevicePowerState,
  3006. irpStack->Parameters.Power.State
  3007. );
  3008. }
  3009. } else {
  3010. // We are already in the given state
  3011. passItDown = FALSE;
  3012. }
  3013. } else {
  3014. status = STATUS_INVALID_DEVICE_REQUEST;
  3015. }
  3016. }
  3017. if (NT_SUCCESS(status) && passItDown) {
  3018. if ((irpStack->Parameters.Power.Type == DevicePowerState) &&
  3019. (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD3)) {
  3020. // Getting out of D0 - cancel the timer
  3021. if (timerWasStarted) {
  3022. KeCancelTimer(&timerObject);
  3023. timerWasStarted = FALSE;
  3024. }
  3025. }
  3026. if (irpStack->Parameters.Power.Type == SystemPowerState) {
  3027. //
  3028. // When we get a System Power IRP (S IRP) the correct thing to do
  3029. // is to request a D, and pass the S IRP as context to the D IRP
  3030. // completion routine. Once the D IRP completes we can pass
  3031. // down the S IRP
  3032. //
  3033. POWER_STATE powerState;
  3034. // Switch to the appropriate device power state
  3035. if (context->PowerState.SystemState == PowerSystemWorking) {
  3036. powerState.DeviceState = PowerDeviceD0;
  3037. } else {
  3038. // We don't need to take special care of leaving the device
  3039. // in powered state in case of hibernation, because it cannot
  3040. // be switched off. Since the device is always on it is enough
  3041. // to send PowerDeviceD3 thus simulating power off.
  3042. powerState.DeviceState = PowerDeviceD3;
  3043. }
  3044. // Transitioned to system state
  3045. fdoExtension->SystemPowerState = context->PowerState.SystemState;
  3046. // Request the IRP for D Power
  3047. status = PoRequestPowerIrp (
  3048. DeviceObject,
  3049. IRP_MN_SET_POWER,
  3050. powerState,
  3051. TrueffsFdoDevicePowerIrpCompletionRoutine,
  3052. Irp,
  3053. NULL
  3054. );
  3055. if (NT_SUCCESS(status)) {
  3056. status = STATUS_PENDING;
  3057. }
  3058. // In this case we should free the context pool because it wont
  3059. // reach the completion callback routine
  3060. ExFreePool(context);
  3061. } else {
  3062. //
  3063. // Its a D irp, we just want to pass down (device power)
  3064. //
  3065. // Send the IRP to the pdo
  3066. IoCopyCurrentIrpStackLocationToNext (Irp);
  3067. IoSetCompletionRoutine(Irp,
  3068. TrueffsFdoPowerCompletionRoutine,
  3069. context,
  3070. TRUE,
  3071. TRUE,
  3072. TRUE);
  3073. status = PoCallDriver(fdoExtension->LowerDeviceObject, Irp);
  3074. }
  3075. return (status);
  3076. } else {
  3077. // Unblock the power IRPs and complete the current IRP
  3078. Irp->IoStatus.Information = 0;
  3079. Irp->IoStatus.Status = status;
  3080. PoStartNextPowerIrp (Irp);
  3081. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  3082. if (context) {
  3083. ExFreePool (context);
  3084. }
  3085. return status;
  3086. }
  3087. }
  3088. NTSTATUS
  3089. TrueffsFdoDevicePowerIrpCompletionRoutine(
  3090. IN PDEVICE_OBJECT DeviceObject,
  3091. IN UCHAR MinorFunction,
  3092. IN POWER_STATE PowerState,
  3093. IN PVOID contextIrp,
  3094. IN PIO_STATUS_BLOCK IoStatus
  3095. )
  3096. /*++
  3097. Routine Description
  3098. Completion routine for Device Power IRPS. The context will be the S power IRP
  3099. that was received, and we can now send down the stack
  3100. Parameters
  3101. DeviceObject - Pointer to FDO for the controller
  3102. Irp - Pointer to the D power irp which is completing
  3103. context - Pointer to the S power irp that can now be sent down the stack
  3104. --*/
  3105. {
  3106. PIRP systemPowerIrp = (PIRP) contextIrp;
  3107. PDEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
  3108. NTSTATUS status;
  3109. PFDO_POWER_CONTEXT context = NULL;
  3110. PIO_STACK_LOCATION irpStack = NULL;
  3111. if (!NT_SUCCESS(IoStatus->Status)) {
  3112. // The D IRP is not allowed to fail
  3113. ASSERT(0);
  3114. }
  3115. //
  3116. // Allocate space for the context of the S IRP completion routine
  3117. //
  3118. context = ExAllocatePoolWithTag (NonPagedPool, sizeof(FDO_POWER_CONTEXT), TFFSPORT_POOL_TAG);
  3119. if (context == NULL) {
  3120. status = STATUS_INSUFFICIENT_RESOURCES;
  3121. // Unblock the power IRPs and complete the current IRP
  3122. systemPowerIrp->IoStatus.Information = 0;
  3123. systemPowerIrp->IoStatus.Status = status;
  3124. PoStartNextPowerIrp (systemPowerIrp);
  3125. IoCompleteRequest(systemPowerIrp, IO_NO_INCREMENT);
  3126. } else {
  3127. // Clear the memory we just allocated
  3128. RtlZeroMemory (context, sizeof(FDO_POWER_CONTEXT));
  3129. // Get current IRP Stack for S-IRP
  3130. irpStack = IoGetCurrentIrpStackLocation (systemPowerIrp);
  3131. ASSERT(irpStack);
  3132. context->PowerType = irpStack->Parameters.Power.Type;
  3133. context->PowerState = irpStack->Parameters.Power.State;
  3134. // The D IRP has completed, now we can send the S IRP down
  3135. IoCopyCurrentIrpStackLocationToNext (systemPowerIrp);
  3136. IoSetCompletionRoutine(systemPowerIrp,
  3137. TrueffsFdoPowerCompletionRoutine,
  3138. context,
  3139. TRUE,
  3140. TRUE,
  3141. TRUE);
  3142. status = PoCallDriver(fdoExtension->LowerDeviceObject, systemPowerIrp);
  3143. }
  3144. return (status);
  3145. }
  3146. NTSTATUS
  3147. TrueffsFdoPowerCompletionRoutine (
  3148. IN PDEVICE_OBJECT DeviceObject,
  3149. IN PIRP Irp,
  3150. IN PVOID Context
  3151. )
  3152. /*++
  3153. Routine Description
  3154. Completion routine for the power IRP sent down to the PDO for the
  3155. controller. If we are getting out of a working system state,
  3156. requests a power IRP to put the device in an appropriate device power state.
  3157. Parameters
  3158. DeviceObject - Pointer to FDO for the controller
  3159. Irp - Pointer to the IRP for the power request
  3160. Context - Pointer to the FDO_POWER_CONTEXT which is
  3161. filled in when the IRP is passed down
  3162. Return Value
  3163. Status
  3164. --*/
  3165. {
  3166. PFDO_POWER_CONTEXT context = Context;
  3167. BOOLEAN callPoSetPowerState;
  3168. PDEVICE_EXTENSION fdoExtension;
  3169. fdoExtension = DeviceObject->DeviceExtension;
  3170. if ((NT_SUCCESS(Irp->IoStatus.Status))) {
  3171. callPoSetPowerState = TRUE;
  3172. if (context->PowerType == SystemPowerState) {
  3173. // Do Nothing
  3174. } else if (context->PowerType == DevicePowerState) {
  3175. if (fdoExtension->DevicePowerState == PowerDeviceD0) {
  3176. // PoSetPowerState is called before we get out of D0
  3177. callPoSetPowerState = FALSE;
  3178. }
  3179. else if (context->PowerState.DeviceState == PowerDeviceD0) {
  3180. // Getting back to D0, set the timer on
  3181. startIntervalTimer();
  3182. }
  3183. fdoExtension->DevicePowerState = context->PowerState.DeviceState;
  3184. } else {
  3185. // How did we not get either a SystemPowerState or a DevicePowerState
  3186. ASSERT(0);
  3187. }
  3188. if (callPoSetPowerState) {
  3189. PoSetPowerState (
  3190. DeviceObject,
  3191. context->PowerType,
  3192. context->PowerState
  3193. );
  3194. }
  3195. }
  3196. ExFreePool(Context);
  3197. PoStartNextPowerIrp (Irp);
  3198. return Irp->IoStatus.Status;
  3199. }
  3200. NTSTATUS
  3201. TrueffsSetPdoDevicePowerState( IN PDEVICE_OBJECT Pdo,
  3202. IN OUT PIRP Irp
  3203. )
  3204. {
  3205. PPDO_EXTENSION pdoExtension = Pdo->DeviceExtension;
  3206. PDEVICE_EXTENSION deviceExtension;
  3207. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  3208. DEVICE_POWER_STATE newDevicePowerState;
  3209. NTSTATUS status;
  3210. BOOLEAN setPowerRequest, powerUp, powerUpParent;
  3211. KIRQL cIrql;
  3212. status = STATUS_SUCCESS;
  3213. newDevicePowerState = irpStack->Parameters.Power.State.DeviceState;
  3214. deviceExtension = pdoExtension->Pext;
  3215. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Transition to device power state: %d\n", newDevicePowerState));
  3216. setPowerRequest = FALSE;
  3217. powerUp = FALSE;
  3218. powerUpParent=FALSE;
  3219. if (pdoExtension->DevicePowerState == newDevicePowerState) {
  3220. return STATUS_SUCCESS;
  3221. }
  3222. if (pdoExtension->DevicePowerState == PowerDeviceD0) {
  3223. // Getting out of D0 - Call PoSetPowerState first
  3224. POWER_STATE newPowerState;
  3225. newPowerState.DeviceState = newDevicePowerState;
  3226. PoSetPowerState(Pdo,
  3227. DevicePowerState,
  3228. newPowerState);
  3229. }
  3230. if (newDevicePowerState == PowerDeviceD0 ||
  3231. newDevicePowerState == PowerDeviceD1 ||
  3232. newDevicePowerState == PowerDeviceD2) {
  3233. if (pdoExtension->DevicePowerState == PowerDeviceD3) {
  3234. // D3 --> D0, D1 or D2 .. Wake up
  3235. powerUpParent = TRUE;
  3236. setPowerRequest = TRUE;
  3237. powerUp = TRUE;
  3238. }
  3239. }
  3240. else { /* newDevicePowerState == D3 */
  3241. if (pdoExtension->DevicePowerState != PowerDeviceD3) {
  3242. // We need to power down now.
  3243. setPowerRequest=TRUE;
  3244. }
  3245. }
  3246. if (setPowerRequest && NT_SUCCESS(status)) {
  3247. // Parent might have to be powered up..
  3248. if (powerUpParent) {
  3249. status = TrueffsFdoChildRequestPowerUp(pdoExtension->Pext,
  3250. pdoExtension,
  3251. Irp);
  3252. } else {
  3253. if (powerUp) {
  3254. /* MDOC PLUS */
  3255. /*
  3256. DOC2window *memWinPtr;
  3257. memWinPtr = (DOC2window *) pdoExtension->Pext->pcmciaParams.windowBase;
  3258. tffsWriteByte(memWinPtr->DOCcontrol, ASIC_RESET_MODE);
  3259. tffsWriteByte(memWinPtr->DOCcontrol, ASIC_RESET_MODE);
  3260. tffsWriteByte(memWinPtr->DOCcontrol, ASIC_NORMAL_MODE);
  3261. tffsWriteByte(memWinPtr->DOCcontrol, ASIC_NORMAL_MODE);
  3262. */
  3263. MDOCPwindow *memWinPtr;
  3264. memWinPtr = (MDOCPwindow *) pdoExtension->Pext->pcmciaParams.windowBase;
  3265. tffsWriteByte(memWinPtr->DOCcontrol, (unsigned char)0x04);
  3266. tffsWriteByte(memWinPtr->DocCntConfirmReg, (unsigned char)0xfb);
  3267. tffsWriteByte(memWinPtr->DOCcontrol, (unsigned char)0x05);
  3268. tffsWriteByte(memWinPtr->DocCntConfirmReg, (unsigned char)0xfa);
  3269. KeAcquireSpinLock(&pdoExtension->Pext->ExtensionDataSpinLock,&cIrql);
  3270. pdoExtension->Pext->DeviceFlags &= ~DEVICE_FLAG_HOLD_IRPS;
  3271. KeReleaseSpinLock(&pdoExtension->Pext->ExtensionDataSpinLock,cIrql);
  3272. if (!KeReadStateSemaphore(&pdoExtension->Pext->requestSemaphore)) {
  3273. KeReleaseSemaphore(&pdoExtension->Pext->requestSemaphore,(KPRIORITY) 0,1,FALSE);
  3274. }
  3275. } else {
  3276. KeAcquireSpinLock(&pdoExtension->Pext->ExtensionDataSpinLock,&cIrql);
  3277. pdoExtension->Pext->DeviceFlags |= DEVICE_FLAG_HOLD_IRPS;
  3278. KeReleaseSpinLock(&pdoExtension->Pext->ExtensionDataSpinLock,cIrql);
  3279. //
  3280. // if (pdoExtension->Pext->DeviceFlags & DEVICE_FLAG_THREAD) {
  3281. //
  3282. if (deviceExtension->TffsportThreadObject) {
  3283. KeWaitForSingleObject(&pdoExtension->Pext->PendingIRPEvent, Executive, KernelMode, FALSE, NULL);
  3284. }
  3285. }
  3286. }
  3287. }
  3288. return status;
  3289. }
  3290. NTSTATUS
  3291. TrueffsSetPdoSystemPowerState (
  3292. IN PDEVICE_OBJECT DeviceObject,
  3293. IN OUT PIRP Irp
  3294. )
  3295. {
  3296. NTSTATUS status;
  3297. PIO_STACK_LOCATION irpStack;
  3298. PPDO_EXTENSION pdoExtension;
  3299. SYSTEM_POWER_STATE newSystemState;
  3300. POWER_STATE powerState;
  3301. pdoExtension = DeviceObject->DeviceExtension;
  3302. status = STATUS_SUCCESS;
  3303. irpStack = IoGetCurrentIrpStackLocation (Irp);
  3304. newSystemState = irpStack->Parameters.Power.State.SystemState;
  3305. if (pdoExtension->SystemPowerState != newSystemState) {
  3306. if (pdoExtension->SystemPowerState == PowerSystemWorking) {
  3307. // Getting out of working state.
  3308. if ((newSystemState == PowerSystemHibernate) &&
  3309. pdoExtension->HiberPathCount) {
  3310. // spin up for the hiber dump driver
  3311. powerState.DeviceState = PowerDeviceD0;
  3312. } else {
  3313. // put the device to D3
  3314. // Issue a D3 to top of my drive stack
  3315. powerState.DeviceState = PowerDeviceD3;
  3316. }
  3317. status = PoRequestPowerIrp (
  3318. DeviceObject,
  3319. IRP_MN_SET_POWER,
  3320. powerState,
  3321. TrueffsPdoRequestPowerCompletionRoutine,
  3322. Irp,
  3323. NULL
  3324. );
  3325. if (NT_SUCCESS(status)) {
  3326. status = STATUS_PENDING;
  3327. }
  3328. } else {
  3329. if (newSystemState == PowerSystemWorking) {
  3330. powerState.DeviceState = PowerDeviceD0;
  3331. } else {
  3332. powerState.DeviceState = PowerDeviceD3;
  3333. }
  3334. status = PoRequestPowerIrp (
  3335. DeviceObject,
  3336. IRP_MN_SET_POWER,
  3337. powerState,
  3338. TrueffsPdoRequestPowerCompletionRoutine,
  3339. Irp,
  3340. NULL
  3341. );
  3342. if (NT_SUCCESS(status)) {
  3343. status = STATUS_PENDING;
  3344. }
  3345. }
  3346. }
  3347. return status;
  3348. }
  3349. NTSTATUS
  3350. TrueffsSetPdoPowerState(
  3351. IN PDEVICE_OBJECT Pdo,
  3352. IN OUT PIRP Irp
  3353. )
  3354. {
  3355. NTSTATUS status;
  3356. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  3357. IoMarkIrpPending(Irp);
  3358. if (irpStack->Parameters.Power.Type == DevicePowerState) {
  3359. status = TrueffsSetPdoDevicePowerState(Pdo, Irp);
  3360. } else if (irpStack->Parameters.Power.Type == SystemPowerState) {
  3361. status = TrueffsSetPdoSystemPowerState(Pdo, Irp);
  3362. } else {
  3363. status = STATUS_NOT_IMPLEMENTED;
  3364. }
  3365. if (status != STATUS_PENDING) {
  3366. Irp->IoStatus.Status = status;
  3367. TrueffsPdoCompletePowerIrp(Pdo, Irp);
  3368. }
  3369. return status;
  3370. }
  3371. VOID
  3372. TrueffsPdoCompletePowerIrp (
  3373. IN PDEVICE_OBJECT DeviceObject,
  3374. IN PIRP Irp
  3375. )
  3376. {
  3377. PPDO_EXTENSION pdoExtension;
  3378. PDEVICE_EXTENSION fdoExtension;
  3379. PIO_STACK_LOCATION irpStack;
  3380. BOOLEAN callPoSetPowerState;
  3381. irpStack = IoGetCurrentIrpStackLocation (Irp);
  3382. pdoExtension = DeviceObject->DeviceExtension;
  3383. fdoExtension = pdoExtension->Pext;
  3384. if (NT_SUCCESS(Irp->IoStatus.Status)) {
  3385. callPoSetPowerState = TRUE;
  3386. Irp->IoStatus.Information = irpStack->Parameters.Power.State.DeviceState;
  3387. if (irpStack->Parameters.Power.Type == SystemPowerState) {
  3388. if (pdoExtension->SystemPowerState != irpStack->Parameters.Power.State.SystemState) {
  3389. pdoExtension->SystemPowerState = Irp->IoStatus.Information;
  3390. }
  3391. } else { /* if (irpStack->Parameters.Power.Type == DevicePowerState) */
  3392. if (pdoExtension->DevicePowerState == PowerDeviceD0) {
  3393. // PoSetPowerState is called before we power down
  3394. callPoSetPowerState = FALSE;
  3395. }
  3396. if (pdoExtension->DevicePowerState != irpStack->Parameters.Power.State.DeviceState) {
  3397. if (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD3) {
  3398. // tell parent that we just fell to sleep
  3399. TrueffsFdoChildReportPowerDown(fdoExtension);
  3400. }
  3401. pdoExtension->DevicePowerState = Irp->IoStatus.Information;
  3402. }
  3403. }
  3404. if (callPoSetPowerState) {
  3405. // we didn't get out of device D0 state. calling PoSetPowerState now
  3406. PoSetPowerState (
  3407. pdoExtension->DeviceObject,
  3408. irpStack->Parameters.Power.Type,
  3409. irpStack->Parameters.Power.State
  3410. );
  3411. }
  3412. }
  3413. PoStartNextPowerIrp (Irp);
  3414. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  3415. }
  3416. VOID
  3417. TrueffsPdoRequestPowerCompletionRoutine(
  3418. IN PDEVICE_OBJECT Pdo,
  3419. IN UCHAR MinorFunction,
  3420. IN POWER_STATE PowerState,
  3421. IN PVOID Context,
  3422. IN PIO_STATUS_BLOCK IoStatus
  3423. )
  3424. {
  3425. PIO_STACK_LOCATION irpStack;
  3426. PIRP irp = Context;
  3427. irp->IoStatus.Status = IoStatus->Status;
  3428. TrueffsPdoCompletePowerIrp (Pdo,irp);
  3429. return;
  3430. }
  3431. NTSTATUS
  3432. TrueffsParentPowerUpCompletionRoutine(
  3433. IN PVOID Context,
  3434. IN NTSTATUS FdoStatus
  3435. )
  3436. /*++
  3437. Routine Description
  3438. Completion routine for powering up the controller.
  3439. Arguments
  3440. Context - Context passed in - this is a pointer to the device extension of
  3441. the disk which originally triggered the power-up of the controller
  3442. FdoStatus - Status of the power up operation of the controller
  3443. Return Value
  3444. status
  3445. --*/
  3446. {
  3447. PPDO_EXTENSION pdoExtension = Context;
  3448. PIRP irp;
  3449. NTSTATUS status = FdoStatus;
  3450. KIRQL cIrql;
  3451. if (NT_SUCCESS(FdoStatus)) {
  3452. // Parent woke up..
  3453. /* MDOC PLUS */
  3454. MDOCPwindow *memWinPtr;
  3455. DOC2window *memDOC2000WinPtr;
  3456. volatile UCHAR chipId = 0;
  3457. memDOC2000WinPtr = (DOC2window *) pdoExtension->Pext->pcmciaParams.windowBase;
  3458. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, ASIC_RESET_MODE);
  3459. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, ASIC_RESET_MODE);
  3460. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, ASIC_NORMAL_MODE);
  3461. tffsWriteByte(memDOC2000WinPtr->DOCcontrol, ASIC_NORMAL_MODE);
  3462. chipId = tffsReadByte(memDOC2000WinPtr->chipId);
  3463. if((chipId == 0x20) || (chipId == 0x30)){
  3464. }
  3465. else{
  3466. /* MDOC PLUS */
  3467. memWinPtr = (MDOCPwindow *) pdoExtension->Pext->pcmciaParams.windowBase;
  3468. tffsWriteByte(memWinPtr->DOCcontrol, (unsigned char)0x04);
  3469. tffsWriteByte(memWinPtr->DocCntConfirmReg, (unsigned char)0xfb);
  3470. tffsWriteByte(memWinPtr->DOCcontrol, (unsigned char)0x05);
  3471. tffsWriteByte(memWinPtr->DocCntConfirmReg, (unsigned char)0xfa);
  3472. }
  3473. KeAcquireSpinLock(&pdoExtension->Pext->ExtensionDataSpinLock,&cIrql);
  3474. pdoExtension->Pext->DeviceFlags &= ~DEVICE_FLAG_HOLD_IRPS;
  3475. KeReleaseSpinLock(&pdoExtension->Pext->ExtensionDataSpinLock,cIrql);
  3476. if (!KeReadStateSemaphore(&pdoExtension->Pext->requestSemaphore)) {
  3477. KeReleaseSemaphore(&pdoExtension->Pext->requestSemaphore,(KPRIORITY) 0,1,FALSE);
  3478. }
  3479. }
  3480. if ((irp = pdoExtension->PendingPowerIrp)!=NULL) {
  3481. // This is the IRP (for the pdo) that originally caused us to power up the parent
  3482. // Complete it now
  3483. irp->IoStatus.Status = status;
  3484. pdoExtension->PendingPowerIrp = NULL;
  3485. TrueffsPdoCompletePowerIrp(pdoExtension->DeviceObject, irp);
  3486. }
  3487. return status;
  3488. }
  3489. NTSTATUS
  3490. TrueffsFdoChildRequestPowerUp (
  3491. IN PDEVICE_EXTENSION FdoExtension,
  3492. IN PPDO_EXTENSION PdoExtension,
  3493. IN PIRP Irp
  3494. )
  3495. /*++
  3496. Routine Description
  3497. This routine is called whenever a disk needs to be powered up due to
  3498. a device state change. This routine would then check if the controller
  3499. is powered down and if so, it would request a power IRP to power up the
  3500. controller
  3501. Arguments
  3502. FdoExtension - Pointer to the device extension for the FDO of the
  3503. controller
  3504. PdoExtension - Pointer to the device extension for the PDO of the
  3505. disk. This is required so that this routine can
  3506. call a completion routine on behalf of the PDO when
  3507. the controller is powered up with the appropriate context
  3508. Irp - Irp that needs to be completed when the controller is
  3509. powered up
  3510. Return Value:
  3511. status
  3512. --*/
  3513. {
  3514. NTSTATUS status;
  3515. POWER_STATE powerState;
  3516. status = STATUS_SUCCESS;
  3517. if (InterlockedCompareExchange(&FdoExtension->NumberOfDisksPoweredUp, 0, 0) == 0) {
  3518. // One of the children is coming out of sleep,
  3519. // we need to power up the parent (the controller)
  3520. powerState.DeviceState = PowerDeviceD0;
  3521. // Passed in IRP needs to be completed after
  3522. // parent powers up
  3523. PdoExtension->PendingPowerIrp = Irp;
  3524. status = PoRequestPowerIrp (FdoExtension->DeviceObject,
  3525. IRP_MN_SET_POWER,
  3526. powerState,
  3527. TrueffsFdoChildRequestPowerUpCompletionRoutine,
  3528. PdoExtension, // Context
  3529. NULL
  3530. );
  3531. if (!NT_SUCCESS(status)) {
  3532. return status;
  3533. }
  3534. status = STATUS_PENDING;
  3535. } else {
  3536. InterlockedIncrement(&FdoExtension->NumberOfDisksPoweredUp);
  3537. TrueffsParentPowerUpCompletionRoutine(
  3538. PdoExtension,
  3539. (NTSTATUS) STATUS_SUCCESS
  3540. );
  3541. }
  3542. return status;
  3543. }
  3544. NTSTATUS
  3545. TrueffsFdoChildRequestPowerUpCompletionRoutine (
  3546. IN PDEVICE_OBJECT DeviceObject,
  3547. IN UCHAR MinorFunction,
  3548. IN POWER_STATE PowerState,
  3549. IN PVOID Context,
  3550. IN PIO_STATUS_BLOCK IoStatus
  3551. )
  3552. /*++
  3553. Routine Description
  3554. Completion routine for a request by a disk to power-up the parent controller.
  3555. Arguments
  3556. DeviceObject - Pointer to the Fdo for the controller
  3557. MinorFunction - Minor function of the IRP_MJ_POWER request
  3558. PowerState - Power state requested (should be D0)
  3559. Context - Context passed in to the completion routine
  3560. IoStatus - Pointer to the status block which will contain
  3561. the returned status
  3562. Return Value:
  3563. status
  3564. --*/
  3565. {
  3566. PDEVICE_EXTENSION fdoExtension;
  3567. fdoExtension = DeviceObject->DeviceExtension;
  3568. if (NT_SUCCESS(IoStatus->Status)) {
  3569. InterlockedIncrement(&fdoExtension->NumberOfDisksPoweredUp);
  3570. }
  3571. TrueffsParentPowerUpCompletionRoutine(
  3572. Context,
  3573. (NTSTATUS) IoStatus->Status
  3574. );
  3575. return IoStatus->Status;
  3576. }
  3577. VOID
  3578. TrueffsFdoChildReportPowerDown (
  3579. IN PDEVICE_EXTENSION FdoExtension
  3580. )
  3581. /*++
  3582. Routine Description
  3583. This routine is called whenever a disk is powered down due to
  3584. a device state change. This routine would then determine if ALL
  3585. disks controlled by the controller are powered down, and if
  3586. so, it would request a power IRP to power the controller itself down
  3587. Arguments
  3588. FdoExtension - Pointer to the device extension for the FDO of the controller
  3589. Return Value:
  3590. None
  3591. --*/
  3592. {
  3593. POWER_STATE powerState;
  3594. InterlockedDecrement(&FdoExtension->NumberOfDisksPoweredUp);
  3595. if (InterlockedCompareExchange(&FdoExtension->NumberOfDisksPoweredUp, 0, 0) == 0) {
  3596. // All the children are powered down, we can now power down
  3597. // the parent (the controller)
  3598. powerState.DeviceState = PowerDeviceD3;
  3599. PoRequestPowerIrp (
  3600. FdoExtension->DeviceObject,
  3601. IRP_MN_SET_POWER,
  3602. powerState,
  3603. NULL,
  3604. NULL,
  3605. NULL
  3606. );
  3607. }
  3608. return;
  3609. }
  3610. NTSTATUS
  3611. TrueffsScsiRequests(
  3612. IN PDEVICE_OBJECT DeviceObject,
  3613. IN PIRP Irp
  3614. )
  3615. {
  3616. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  3617. PDEVICE_EXTENSION_HEADER devExtension;
  3618. PDEVICE_EXTENSION deviceExtension;
  3619. PSCSI_REQUEST_BLOCK srb;
  3620. NTSTATUS status;
  3621. KIRQL cIrql;
  3622. devExtension = (PDEVICE_EXTENSION_HEADER) DeviceObject->DeviceExtension;
  3623. if (IS_FDO(devExtension))
  3624. {
  3625. deviceExtension = DeviceObject->DeviceExtension;
  3626. }
  3627. else
  3628. {
  3629. PPDO_EXTENSION pdoExtension = DeviceObject->DeviceExtension;
  3630. deviceExtension = pdoExtension->Pext;
  3631. }
  3632. //
  3633. // Get a pointer to the scsi request block
  3634. //
  3635. srb = irpStack->Parameters.Scsi.Srb;
  3636. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: ScsiRequests for %Xh device object, function %Xh\n", DeviceObject, srb->Function));
  3637. if (deviceExtension->DeviceFlags & DEVICE_FLAG_REMOVED)
  3638. {
  3639. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: ScsiRequests: Device does not exist\n"));
  3640. status = STATUS_DEVICE_DOES_NOT_EXIST;
  3641. srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  3642. Irp->IoStatus.Status = status;
  3643. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3644. return status;
  3645. }
  3646. if (srb->Function == SRB_FUNCTION_CLAIM_DEVICE)
  3647. {
  3648. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: ScsiRequests: ClaimDevice\n"));
  3649. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  3650. if (deviceExtension->DeviceFlags & DEVICE_FLAG_CLAIMED)
  3651. {
  3652. status = STATUS_DEVICE_BUSY;
  3653. srb->SrbStatus = SRB_STATUS_BUSY;
  3654. }
  3655. else
  3656. {
  3657. deviceExtension->DeviceFlags |= DEVICE_FLAG_CLAIMED;
  3658. srb->DataBuffer = DeviceObject;
  3659. status = STATUS_SUCCESS;
  3660. srb->SrbStatus = SRB_STATUS_SUCCESS;
  3661. }
  3662. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  3663. Irp->IoStatus.Status = status;
  3664. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3665. return status;
  3666. }
  3667. if (srb->Function == SRB_FUNCTION_RELEASE_DEVICE)
  3668. {
  3669. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: ScsiRequests: ReleaseDevice\n"));
  3670. KeAcquireSpinLock(&deviceExtension->ExtensionDataSpinLock,&cIrql);
  3671. deviceExtension->DeviceFlags &= ~DEVICE_FLAG_CLAIMED;
  3672. KeReleaseSpinLock(&deviceExtension->ExtensionDataSpinLock,cIrql);
  3673. status = STATUS_SUCCESS;
  3674. srb->SrbStatus = SRB_STATUS_SUCCESS;
  3675. Irp->IoStatus.Status = status;
  3676. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3677. return status;
  3678. }
  3679. if ((srb->Function == SRB_FUNCTION_FLUSH_QUEUE) || (srb->Function == SRB_FUNCTION_FLUSH))
  3680. {
  3681. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: ScsiRequests: Flush or FlushQueue\n"));
  3682. srb->SrbStatus = SRB_STATUS_SUCCESS;
  3683. status = STATUS_SUCCESS;
  3684. Irp->IoStatus.Status = status;
  3685. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3686. return STATUS_SUCCESS;
  3687. }
  3688. if (srb->Function == SRB_FUNCTION_RESET_BUS)
  3689. {
  3690. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: ScsiRequests: ResetBus\n"));
  3691. srb->SrbStatus = SRB_STATUS_SUCCESS;
  3692. status = STATUS_SUCCESS;
  3693. Irp->IoStatus.Status = status;
  3694. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3695. return status;
  3696. }
  3697. if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI)
  3698. {
  3699. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: ScsiRequests: unsupported function\n"));
  3700. status = STATUS_NOT_SUPPORTED;
  3701. srb->SrbStatus = SRB_STATUS_ERROR;
  3702. Irp->IoStatus.Status = status;
  3703. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3704. return status;
  3705. }
  3706. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: ScsiRequests: ExecuteScsi\n"));
  3707. IoMarkIrpPending(Irp);
  3708. IoStartPacket(DeviceObject, Irp, NULL, NULL);
  3709. return STATUS_PENDING;
  3710. }
  3711. VOID
  3712. TrueffsStartIo (
  3713. IN PDEVICE_OBJECT DeviceObject,
  3714. IN PIRP Irp
  3715. )
  3716. /*++
  3717. Routine Description:
  3718. Arguments:
  3719. DeviceObject - Supplies pointer to Adapter device object.
  3720. Irp - Supplies a pointer to an IRP.
  3721. Return Value:
  3722. Nothing.
  3723. --*/
  3724. {
  3725. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  3726. PSCSI_REQUEST_BLOCK srb = irpStack->Parameters.Scsi.Srb;
  3727. PDEVICE_EXTENSION_HEADER devExtension;
  3728. PPDO_EXTENSION pdoExtension;
  3729. PDEVICE_EXTENSION deviceExtension;
  3730. NTSTATUS status;
  3731. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo\n"));
  3732. devExtension = (PDEVICE_EXTENSION_HEADER) DeviceObject->DeviceExtension;
  3733. if (IS_FDO(devExtension)) {
  3734. deviceExtension = DeviceObject->DeviceExtension;
  3735. pdoExtension = deviceExtension->ChildPdo->DeviceExtension;
  3736. }
  3737. else {
  3738. pdoExtension = DeviceObject->DeviceExtension;
  3739. deviceExtension = pdoExtension->Pext;
  3740. }
  3741. if (deviceExtension->DeviceFlags & DEVICE_FLAG_REMOVED) {
  3742. // we got REMOVE_DEVICE, we can't accept any more requests...
  3743. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartIo: Device does not exist\n"));
  3744. status = STATUS_DEVICE_DOES_NOT_EXIST;
  3745. srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  3746. Irp->IoStatus.Status = status;
  3747. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  3748. IoStartNextPacket(DeviceObject,FALSE);
  3749. return;
  3750. }
  3751. status = QueueIrpToThread(Irp, deviceExtension);
  3752. if (status != STATUS_PENDING) {
  3753. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartIo: QueueIrpToThread failed with status %Xh\n", status));
  3754. Irp->IoStatus.Status = status;
  3755. srb->SrbStatus = SRB_STATUS_ERROR;
  3756. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  3757. return;
  3758. }
  3759. if (pdoExtension->IdleCounter) {
  3760. PoSetDeviceBusy(pdoExtension->IdleCounter);
  3761. }
  3762. if (pdoExtension->DevicePowerState != PowerDeviceD0 &&
  3763. pdoExtension->SystemPowerState == PowerSystemWorking) {
  3764. // We are not powered up.
  3765. // issue an power up
  3766. POWER_STATE powerState;
  3767. powerState.DeviceState = PowerDeviceD0;
  3768. PoRequestPowerIrp (
  3769. pdoExtension->DeviceObject,
  3770. IRP_MN_SET_POWER,
  3771. powerState,
  3772. NULL,
  3773. NULL,
  3774. NULL
  3775. );
  3776. }
  3777. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Irp queued\n"));
  3778. Irp->IoStatus.Status = STATUS_PENDING;
  3779. srb->SrbStatus = SRB_STATUS_PENDING;
  3780. IoStartNextPacket(DeviceObject,FALSE);
  3781. return;
  3782. }
  3783. VOID
  3784. TrueffsThread(
  3785. PVOID Context
  3786. )
  3787. /*++
  3788. Routine Description:
  3789. This is the code executed by the system thread created when the
  3790. Trueffs driver initializes. This thread loops forever (or until a
  3791. flag is set telling the thread to kill itself) processing packets
  3792. put into the queue by the dispatch routines.
  3793. Arguments:
  3794. Context - not used.
  3795. Return Value:
  3796. None.
  3797. --*/
  3798. {
  3799. PIRP irp;
  3800. PIO_STACK_LOCATION irpSp;
  3801. PLIST_ENTRY request;
  3802. PDEVICE_EXTENSION deviceExtension = Context;
  3803. PSCSI_REQUEST_BLOCK Srb;
  3804. NTSTATUS ntStatus;
  3805. NTSTATUS waitStatus;
  3806. LARGE_INTEGER queueWait;
  3807. ULONG status;
  3808. ULONG i;
  3809. ULONG startingSector;
  3810. PUCHAR dataOffset;
  3811. PVOID storedSrbDataBuffer = NULL;
  3812. FLStatus tffsStatus = flOK;
  3813. FLStatus flStatusProt = flOK;
  3814. IOreq ioreq;
  3815. IOreq ioreqProt;
  3816. flIOctlRecord flIoctlRec;
  3817. int l;
  3818. CHAR vendorString[8];// = VENDORSTRING;
  3819. CHAR productString[16];// = PRODUCTSTRING;
  3820. CHAR revisionString[4];// = REVISIONSTRING;
  3821. PCHAR pageData;
  3822. ULONG parameterHeaderLength;
  3823. ULONG blockDescriptorLength;
  3824. PCDB cdb;
  3825. BOOLEAN transferForbidden;
  3826. flFormatPhysicalInput flFp;
  3827. flBDKOperationInput bdkOperationInput;
  3828. flOtpInput otpInput;
  3829. flIplInput iplInput;
  3830. flProtectionInput protectionInput;
  3831. void * userInput = NULL;
  3832. void * userOutput = NULL;
  3833. PAGED_CODE();
  3834. queueWait.QuadPart = -(3 * 1000 * 10000);
  3835. do {
  3836. KeSetEvent(&deviceExtension->PendingIRPEvent, 0, FALSE);
  3837. // Wait for a request from the dispatch routines.
  3838. waitStatus = KeWaitForSingleObject(
  3839. (PVOID) &deviceExtension->requestSemaphore,
  3840. Executive,
  3841. KernelMode,
  3842. FALSE,
  3843. &queueWait );
  3844. if (waitStatus == STATUS_SUCCESS && !(deviceExtension->DeviceFlags & DEVICE_FLAG_QUERY_STOP_REMOVE)
  3845. && !(deviceExtension->DeviceFlags & DEVICE_FLAG_HOLD_IRPS)) {
  3846. if(deviceExtension->threadReferenceCount == 0) {
  3847. //TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Thread: going to kill the thread\n"));
  3848. deviceExtension->threadReferenceCount = -1;
  3849. PsTerminateSystemThread( STATUS_SUCCESS );
  3850. }
  3851. }
  3852. else
  3853. continue;
  3854. while (request = ExInterlockedRemoveHeadList(&deviceExtension->listEntry,&deviceExtension->listSpinLock)) {
  3855. KeClearEvent(&deviceExtension->PendingIRPEvent);
  3856. irp = CONTAINING_RECORD( request, IRP, Tail.Overlay.ListEntry );
  3857. irpSp = IoGetCurrentIrpStackLocation( irp );
  3858. //TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Thread: Irp %Xh, IrpSp %Xh\n", irp, irpSp));
  3859. Srb = irpSp->Parameters.Scsi.Srb;
  3860. //TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Thread: Srb %Xh DataBuffer %Xh MdlAddress %Xh\n", Srb, Srb->DataBuffer, irp->MdlAddress));
  3861. transferForbidden = FALSE;
  3862. if (irp->MdlAddress != NULL) {
  3863. PVOID tmpDataBuffer = NULL;
  3864. MM_PAGE_PRIORITY tffsPriority =
  3865. (deviceExtension->PagingPathCount || deviceExtension->CrashDumpPathCount) ?
  3866. HighPagePriority : NormalPagePriority;
  3867. storedSrbDataBuffer = Srb->DataBuffer;
  3868. dataOffset = MmGetSystemAddressForMdlSafe(irp->MdlAddress, tffsPriority);
  3869. if (dataOffset != NULL) {
  3870. tmpDataBuffer = dataOffset + (ULONG)((PUCHAR)Srb->DataBuffer -
  3871. (PCCHAR)MmGetMdlVirtualAddress(irp->MdlAddress));
  3872. //TffsDebugPrint((TFFS_DEB_INFO, "Trueffs: TmpDataBuffer= 0x%x Srb->DataBuffer= 0x%x\n", tmpDataBuffer, Srb->DataBuffer));
  3873. Srb->DataBuffer = tmpDataBuffer;
  3874. }
  3875. else {
  3876. transferForbidden = TRUE;
  3877. TffsDebugPrint ((TFFS_DEB_ERROR,"Trueffs: MmGetSystemAddressForMdlSafe Failed\n"));
  3878. }
  3879. }
  3880. switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
  3881. case IOCTL_TFFS_EXTENDED_WRITE_IPL:
  3882. {
  3883. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  3884. sizeof(flOutputStatusRecord)) {
  3885. status = STATUS_INVALID_PARAMETER;
  3886. irp->IoStatus.Information = 0;
  3887. }
  3888. else if ( irpSp->Parameters.DeviceIoControl.InputBufferLength >
  3889. sizeof(flUserIplInput)){
  3890. status = STATUS_INVALID_PARAMETER;
  3891. irp->IoStatus.Information = 0;
  3892. }
  3893. else {
  3894. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo start get info\n"));
  3895. ioreq.irHandle = deviceExtension->UnitNumber;
  3896. ioreq.irFlags = FL_IOCTL_EXTENDED_WRITE_IPL;
  3897. ioreq.irData = &flIoctlRec;
  3898. iplInput.buf = ((flUserIplInput *)(irp->AssociatedIrp.SystemBuffer))->buf;
  3899. iplInput.bufLen = ((flUserIplInput *)(irp->AssociatedIrp.SystemBuffer))->bufLen;
  3900. flIoctlRec.inputRecord = &iplInput;
  3901. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  3902. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo before flioctl\n"));
  3903. tffsStatus = flIOctl(&ioreq);
  3904. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo after flioctl\n"));
  3905. if( tffsStatus == flOK ) {
  3906. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo FLOK\n"));
  3907. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  3908. status = STATUS_SUCCESS;
  3909. }
  3910. else {
  3911. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo !FLOK!\n"));
  3912. irp->IoStatus.Information = 0;
  3913. status = STATUS_UNSUCCESSFUL;
  3914. }
  3915. }
  3916. irp->IoStatus.Status = status;
  3917. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  3918. continue;
  3919. }
  3920. #ifdef ENVIRONMENT_VARS
  3921. case IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES:
  3922. {
  3923. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  3924. sizeof(flOutputStatusRecord)) {
  3925. status = STATUS_INVALID_PARAMETER;
  3926. irp->IoStatus.Information = 0;
  3927. }
  3928. else if ( irpSp->Parameters.DeviceIoControl.InputBufferLength >
  3929. sizeof(flExtendedEnvVarsInput)){
  3930. status = STATUS_INVALID_PARAMETER;
  3931. irp->IoStatus.Information = 0;
  3932. }
  3933. else {
  3934. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES\n"));
  3935. ioreq.irHandle = deviceExtension->UnitNumber;
  3936. ioreq.irFlags = FL_IOCTL_EXTENDED_ENVIRONMENT_VARIABLES;
  3937. ioreq.irData = &flIoctlRec;
  3938. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  3939. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  3940. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES before flioctl\n"));
  3941. tffsStatus = flIOctl(&ioreq);
  3942. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES after flioctl\n"));
  3943. if( tffsStatus == flOK ) {
  3944. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES FLOK\n"));
  3945. irp->IoStatus.Information = sizeof(flExtendedEnvVarsOutput);
  3946. status = STATUS_SUCCESS;
  3947. }
  3948. else {
  3949. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_EXTENDED_ENVIRONMENT_VARIABLES !FLOK!\n"));
  3950. irp->IoStatus.Information = 0;
  3951. status = STATUS_UNSUCCESSFUL;
  3952. }
  3953. }
  3954. irp->IoStatus.Status = status;
  3955. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  3956. continue;
  3957. }
  3958. #endif /* ENVIRONMENT_VARS */
  3959. case IOCTL_TFFS_CUSTOMER_ID:
  3960. {
  3961. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  3962. sizeof(flCustomerIdOutput)) {
  3963. status = STATUS_INVALID_PARAMETER;
  3964. irp->IoStatus.Information = 0;
  3965. }
  3966. else {
  3967. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo start get info\n"));
  3968. ioreq.irHandle = deviceExtension->UnitNumber;
  3969. ioreq.irFlags = FL_IOCTL_CUSTOMER_ID;
  3970. ioreq.irData = &flIoctlRec;
  3971. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  3972. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo before flioctl\n"));
  3973. tffsStatus = flIOctl(&ioreq);
  3974. //tffsStatus = flOK;
  3975. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo after flioctl\n"));
  3976. if( tffsStatus == flOK ) {
  3977. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo FLOK\n"));
  3978. irp->IoStatus.Information = sizeof(flCustomerIdOutput);
  3979. status = STATUS_SUCCESS;
  3980. }
  3981. else {
  3982. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo !FLOK!\n"));
  3983. irp->IoStatus.Information = 0;
  3984. status = STATUS_UNSUCCESSFUL;
  3985. }
  3986. }
  3987. irp->IoStatus.Status = status;
  3988. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  3989. continue;
  3990. }
  3991. case IOCTL_TFFS_NUMBER_OF_PARTITIONS: { // User TFFS IOCTL - FL_GET_INFO
  3992. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsGetInfo\n"));
  3993. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  3994. sizeof(flCountPartitionsOutput)) {
  3995. status = STATUS_INVALID_PARAMETER;
  3996. irp->IoStatus.Information = 0;
  3997. }
  3998. else {
  3999. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo start get info\n"));
  4000. ioreq.irHandle = deviceExtension->UnitNumber;
  4001. ioreq.irFlags = FL_IOCTL_NUMBER_OF_PARTITIONS;
  4002. ioreq.irData = &flIoctlRec;
  4003. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4004. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo before flioctl\n"));
  4005. tffsStatus = flIOctl(&ioreq);
  4006. //tffsStatus = flOK;
  4007. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo after flioctl\n"));
  4008. if( tffsStatus == flOK ) {
  4009. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo FLOK\n"));
  4010. irp->IoStatus.Information = sizeof(flCountPartitionsOutput);
  4011. status = STATUS_SUCCESS;
  4012. }
  4013. else {
  4014. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo !FLOK!\n"));
  4015. irp->IoStatus.Information = 0;
  4016. status = STATUS_UNSUCCESSFUL;
  4017. }
  4018. }
  4019. irp->IoStatus.Status = status;
  4020. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4021. continue;
  4022. }
  4023. case IOCTL_TFFSFL_UNIQUE_ID:
  4024. { // User TFFS IOCTL -
  4025. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: FL_IOCTL_UNIQUE_ID \n"));
  4026. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4027. sizeof(flUniqueIdOutput)) {
  4028. status = STATUS_INVALID_PARAMETER;
  4029. irp->IoStatus.Information = 0;
  4030. }
  4031. else {
  4032. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_UNIQUE_ID Start\n"));
  4033. ioreq.irHandle = deviceExtension->UnitNumber;
  4034. ioreq.irFlags = FL_IOCTL_UNIQUE_ID;
  4035. ioreq.irData = &flIoctlRec;
  4036. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4037. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo before flioctl\n"));
  4038. tffsStatus = flIOctl(&ioreq);
  4039. //tffsStatus = flOK;
  4040. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo after flioctl\n"));
  4041. if( tffsStatus == flOK ) {
  4042. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo FLOK\n"));
  4043. irp->IoStatus.Information = sizeof(flUniqueIdOutput);
  4044. status = STATUS_SUCCESS;
  4045. }
  4046. else {
  4047. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo !FLOK!\n"));
  4048. irp->IoStatus.Information = 0;
  4049. status = STATUS_UNSUCCESSFUL;
  4050. }
  4051. }
  4052. irp->IoStatus.Status = status;
  4053. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4054. continue;
  4055. }
  4056. case IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE:
  4057. { // User TFFS IOCTL - IOCTL_TFFSFL_INQUIRE_CAPABILITIES
  4058. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE\n"));
  4059. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4060. sizeof(flOutputStatusRecord)) ||
  4061. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4062. sizeof(flUserFormatPhysicalInput))) {
  4063. status = STATUS_INVALID_PARAMETER;
  4064. irp->IoStatus.Information = 0;
  4065. }
  4066. else {
  4067. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE Start\n"));
  4068. userInput = (VOID *)(irp->AssociatedIrp.SystemBuffer); //Get input parameters
  4069. flFp.formatType = ((flUserFormatPhysicalInput *)userInput)->formatType;
  4070. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: formatType:%Xh \n",flFp.formatType));
  4071. flFp.fp.percentUse = (unsigned char)((flUserFormatPhysicalInput *)userInput)->fp.percentUse;
  4072. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: percentUse:%Xh \n",flFp.fp.percentUse));
  4073. flFp.fp.noOfBDTLPartitions = ((flUserFormatPhysicalInput *)userInput)->fp.noOfBDTLPartitions;
  4074. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: noOfBDTLPartitions:%Xh \n",flFp.fp.noOfBDTLPartitions));
  4075. flFp.fp.noOfBinaryPartitions = ((flUserFormatPhysicalInput *)userInput)->fp.noOfBinaryPartitions;
  4076. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: noOfBinaryPartitions:%Xh \n",flFp.fp.noOfBinaryPartitions));
  4077. flFp.fp.BDTLPartitionInfo = ((flUserFormatPhysicalInput *)userInput)->fp.BDTLPartitionInfo;
  4078. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: BDTLPartitionInfo:%Xh \n",flFp.fp.BDTLPartitionInfo));
  4079. flFp.fp.binaryPartitionInfo = ((flUserFormatPhysicalInput *)userInput)->fp.binaryPartitionInfo;
  4080. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: binaryPartitionInfo:%Xh \n",flFp.fp.binaryPartitionInfo));
  4081. #ifdef WRITE_EXB_IMAGE
  4082. flFp.fp.exbBuffer = ((flUserFormatPhysicalInput *)userInput)->fp.exbBuffer;
  4083. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: exbBuffer:%Xh \n",flFp.fp.exbBuffer));
  4084. flFp.fp.exbBufferLen = ((flUserFormatPhysicalInput *)userInput)->fp.exbBufferLen;
  4085. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: exbBufferLen:%Xh \n",flFp.fp.exbBufferLen));
  4086. flFp.fp.exbLen = ((flUserFormatPhysicalInput *)userInput)->fp.exbLen;
  4087. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: exbLen:%Xh \n",flFp.fp.exbLen));
  4088. flFp.fp.exbWindow = ((flUserFormatPhysicalInput *)userInput)->fp.exbWindow;
  4089. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: exbWindow:%Xh \n",flFp.fp.exbWindow));
  4090. flFp.fp.exbFlags = ((flUserFormatPhysicalInput *)userInput)->fp.exbFlags;
  4091. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: exbFlags:%Xh \n",flFp.fp.exbFlags));
  4092. #endif /*WRITE_EXB_IMAGE*/
  4093. flFp.fp.cascadedDeviceNo = ((flUserFormatPhysicalInput *)userInput)->fp.cascadedDeviceNo;
  4094. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: cascadedDeviceNo:%Xh \n",flFp.fp.cascadedDeviceNo));
  4095. flFp.fp.noOfCascadedDevices = ((flUserFormatPhysicalInput *)userInput)->fp.noOfCascadedDevices;
  4096. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: noOfCascadedDevices:%Xh \n",flFp.fp.noOfCascadedDevices));
  4097. flFp.fp.progressCallback = NULL;
  4098. flFp.fp.vmAddressingLimit = ((flUserFormatPhysicalInput *)userInput)->fp.vmAddressingLimit;
  4099. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: vmAddressingLimit:%Xh \n",flFp.fp.vmAddressingLimit));
  4100. flFp.fp.embeddedCISlength = (unsigned short)((flUserFormatPhysicalInput *)userInput)->fp.embeddedCISlength;
  4101. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: embeddedCISlength:%Xh \n",flFp.fp.embeddedCISlength));
  4102. flFp.fp.embeddedCIS = ((flUserFormatPhysicalInput *)userInput)->fp.embeddedCIS;
  4103. TffsDebugPrint((TFFS_DEB_INFO,"TrueffsFORMAT: embeddedCIS:%Xh \n",flFp.fp.embeddedCIS));
  4104. ioreq.irHandle = deviceExtension->UnitNumber;
  4105. ioreq.irFlags = FL_IOCTL_FORMAT_PHYSICAL_DRIVE;
  4106. ioreq.irData = &flIoctlRec;
  4107. flIoctlRec.inputRecord = &flFp;//(VOID *)(irp->AssociatedIrp.SystemBuffer);
  4108. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4109. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE before flioctl\n"));
  4110. tffsStatus = flIOctl(&ioreq);
  4111. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE after flioctl\n"));
  4112. userInput = NULL;
  4113. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE after flioctl - clean userPointer\n"));
  4114. if( tffsStatus == flOK ) {
  4115. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE FLOK\n"));
  4116. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4117. status = STATUS_SUCCESS;
  4118. }
  4119. else {
  4120. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_FORMAT_PHYSICAL_DRIVE Failed!\n"));
  4121. irp->IoStatus.Information = 0;
  4122. status = STATUS_UNSUCCESSFUL;
  4123. }
  4124. }
  4125. irp->IoStatus.Status = status;
  4126. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4127. continue;
  4128. }
  4129. #ifdef VERIFY_VOLUME
  4130. case IOCTL_TFFS_VERIFY_VOLUME:
  4131. {
  4132. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_VERIFY_VOLUME\n"));
  4133. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4134. sizeof(flOutputStatusRecord)) ||
  4135. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4136. sizeof(flVerifyVolumeInput))) {
  4137. status = STATUS_INVALID_PARAMETER;
  4138. irp->IoStatus.Information = 0;
  4139. }
  4140. else {
  4141. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IOCTL_TFFS_VERIFY_VOLUME Start\n"));
  4142. ioreq.irHandle = deviceExtension->UnitNumber;
  4143. ioreq.irFlags = IOCTL_TFFS_VERIFY_VOLUME;
  4144. ioreq.irData = &flIoctlRec;
  4145. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4146. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4147. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IOCTL_TFFS_VERIFY_VOLUME before flioctl\n"));
  4148. tffsStatus = flIOctl(&ioreq);
  4149. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IOCTL_TFFS_VERIFY_VOLUME after flioctl\n"));
  4150. if( tffsStatus == flOK ) {
  4151. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IOCTL_TFFS_VERIFY_VOLUME FLOK\n"));
  4152. irp->IoStatus.Information = sizeof(flVerifyVolumeOutput);
  4153. status = STATUS_SUCCESS;
  4154. }//if( tffsStatus == flOK )
  4155. else {
  4156. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: IOCTL_TFFS_VERIFY_VOLUME Failed!\n"));
  4157. irp->IoStatus.Information = 0;
  4158. status = STATUS_UNSUCCESSFUL;
  4159. }//else( tffsStatus == flOK )
  4160. }//if( (irpSp->Parameters
  4161. irp->IoStatus.Status = status;
  4162. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4163. continue;
  4164. }
  4165. #endif /* VERIFY_VOLUME */
  4166. #ifdef HW_PROTECTION
  4167. case IOCTL_TFFS_BDTL_HW_PROTECTION:
  4168. { // User TFFS IOCTL - IOCTL_TFFS_BDTL_HW_PROTECTION
  4169. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_BDTL_HW_PROTECTION\n"));
  4170. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4171. sizeof(flOutputStatusRecord)) ||
  4172. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4173. sizeof(flProtectionInput))) {
  4174. status = STATUS_INVALID_PARAMETER;
  4175. irp->IoStatus.Information = 0;
  4176. }
  4177. else {
  4178. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDTL_HW_PROTECTION Start\n"));
  4179. ioreq.irHandle = deviceExtension->UnitNumber;
  4180. ioreq.irFlags = FL_IOCTL_BDTL_HW_PROTECTION;
  4181. ioreq.irData = &flIoctlRec;
  4182. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4183. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4184. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDTL_HW_PROTECTION before flioctl\n"));
  4185. tffsStatus = flIOctl(&ioreq);
  4186. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDTL_HW_PROTECTION after flioctl\n"));
  4187. if( tffsStatus == flOK ) {
  4188. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDTL_HW_PROTECTION FLOK\n"));
  4189. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4190. status = STATUS_SUCCESS;
  4191. //Change if protection has been changed
  4192. /*
  4193. //If key inserted
  4194. if(((flProtectionInput *)flIoctlRec.inputRecord)->type == PROTECTION_INSERT_KEY){
  4195. deviceExtension->IsWriteProtected = FALSE;
  4196. }
  4197. //If type changed to protected
  4198. else if((((flProtectionInput *)flIoctlRec.inputRecord)->type == PROTECTION_CHANGE_TYPE) &&
  4199. ((flProtectionInput *)flIoctlRec.inputRecord)->type & (READ_PROTECTED|WRITE_PROTECTED))){
  4200. deviceExtension->IsWriteProtected = TRUE;
  4201. }
  4202. //If type changed to unprotected
  4203. else if((((flProtectionInput *)flIoctlRec.inputRecord)->type == PROTECTION_CHANGE_TYPE) &&
  4204. ((flProtectionInput *)flIoctlRec.inputRecord)->type == PROTECTABLE)){
  4205. deviceExtension->IsWriteProtected = FALSE;
  4206. }
  4207. //If remove key - ask if we are in protectable state.
  4208. else if(((flProtectionInput *)flIoctlRec.inputRecord)->type == PROTECTION_REMOVE_KEY){
  4209. */
  4210. flStatusProt = flOK;
  4211. ioreqProt.irHandle = ioreq.irHandle;
  4212. ioreqProt.irFlags = 0;
  4213. flStatusProt = flIdentifyProtection(&ioreqProt);
  4214. if(flStatusProt == flOK){
  4215. if((ioreqProt.irFlags & (WRITE_PROTECTED |READ_PROTECTED))
  4216. && !(ioreqProt.irFlags & KEY_INSERTED )){
  4217. deviceExtension->IsWriteProtected = TRUE;
  4218. }
  4219. else{
  4220. deviceExtension->IsWriteProtected = FALSE;
  4221. }
  4222. }
  4223. else{
  4224. deviceExtension->IsWriteProtected = FALSE;
  4225. }//(flStatusProt == flOK)
  4226. }//if( tffsStatus == flOK )
  4227. else {
  4228. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDTL_HW_PROTECTION Failed!\n"));
  4229. irp->IoStatus.Information = 0;
  4230. status = STATUS_UNSUCCESSFUL;
  4231. }//else( tffsStatus == flOK )
  4232. }//if( (irpSp->Parameters
  4233. irp->IoStatus.Status = status;
  4234. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4235. continue;
  4236. }
  4237. case IOCTL_TFFS_BINARY_HW_PROTECTION:
  4238. { // User TFFS IOCTL - IOCTL_TFFS_BDTL_HW_PROTECTION
  4239. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_BINARY_HW_PROTECTION\n"));
  4240. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4241. sizeof(flOutputStatusRecord)) ||
  4242. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4243. sizeof(flProtectionInput))) {
  4244. status = STATUS_INVALID_PARAMETER;
  4245. irp->IoStatus.Information = 0;
  4246. }
  4247. else {
  4248. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BINARY_HW_PROTECTION Start\n"));
  4249. //ioreq.irHandle = deviceExtension->UnitNumber;
  4250. ioreq.irFlags = FL_IOCTL_BINARY_HW_PROTECTION;
  4251. ioreq.irData = &flIoctlRec;
  4252. //Update protectionInput with flBDKProtectionInput members
  4253. protectionInput.protectionType = ((flBDKProtectionInput *)(irp->AssociatedIrp.SystemBuffer))->protectionType;
  4254. protectionInput.type = ((flBDKProtectionInput *)(irp->AssociatedIrp.SystemBuffer))->type;
  4255. tffscpy(protectionInput.key , ((flBDKProtectionInput *)(irp->AssociatedIrp.SystemBuffer))->key, sizeof(protectionInput.key));
  4256. ioreq.irHandle = (deviceExtension->UnitNumber & 0x0f) + (((flBDKProtectionInput *)(irp->AssociatedIrp.SystemBuffer))->partitionNumber << 4);
  4257. //flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4258. flIoctlRec.inputRecord = &protectionInput;
  4259. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4260. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BINARY_HW_PROTECTION before flioctl\n"));
  4261. tffsStatus = flIOctl(&ioreq);
  4262. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BINARY_HW_PROTECTION after flioctl\n"));
  4263. if( tffsStatus == flOK ) {
  4264. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BINARY_HW_PROTECTION FLOK\n"));
  4265. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4266. status = STATUS_SUCCESS;
  4267. }
  4268. else {
  4269. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BINARY_HW_PROTECTION Failed!\n"));
  4270. irp->IoStatus.Information = 0;
  4271. status = STATUS_UNSUCCESSFUL;
  4272. }
  4273. }
  4274. irp->IoStatus.Status = status;
  4275. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4276. continue;
  4277. }
  4278. #endif /*HW_PROTECTION*/
  4279. #ifdef WRITE_EXB_IMAGE
  4280. case IOCTL_TFFS_PLACE_EXB_BY_BUFFER:
  4281. {
  4282. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_PLACE_EXB_BY_BUFFER\n"));
  4283. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4284. sizeof(flOutputStatusRecord) )
  4285. || (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4286. sizeof(flUserPlaceExbInput) )) {
  4287. status = STATUS_INVALID_PARAMETER;
  4288. irp->IoStatus.Information = 0;
  4289. }
  4290. else {
  4291. flPlaceExbInput placeExbInput;
  4292. ioreq.irHandle = deviceExtension->UnitNumber;
  4293. ioreq.irFlags = FL_IOCTL_PLACE_EXB_BY_BUFFER;
  4294. ioreq.irData = &flIoctlRec;
  4295. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4296. flIoctlRec.inputRecord = &placeExbInput;
  4297. //Update placeExbInput with flUserPlaceExbInput memebers
  4298. placeExbInput.buf = ((flUserPlaceExbInput *)(irp->AssociatedIrp.SystemBuffer))->buf;
  4299. placeExbInput.bufLen = ((flUserPlaceExbInput *)(irp->AssociatedIrp.SystemBuffer))->bufLen;
  4300. placeExbInput.exbFlags = ((flUserPlaceExbInput *)(irp->AssociatedIrp.SystemBuffer))->exbFlags;
  4301. placeExbInput.exbWindow = ((flUserPlaceExbInput *)(irp->AssociatedIrp.SystemBuffer))->exbWindow;
  4302. tffsStatus = flIOctl(&ioreq);
  4303. if( tffsStatus == flOK ) {
  4304. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo FLOK\n"));
  4305. irp->IoStatus.Information = sizeof(flCountPartitionsOutput);
  4306. status = STATUS_SUCCESS;
  4307. }
  4308. else {
  4309. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo !FLOK!\n"));
  4310. irp->IoStatus.Information = 0;
  4311. status = STATUS_UNSUCCESSFUL;
  4312. }
  4313. }
  4314. irp->IoStatus.Status = status;
  4315. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4316. continue;
  4317. }
  4318. #endif /*WRITE_EXB_IMAGE*/
  4319. #ifdef HW_OTP
  4320. case IOCTL_TFFS_OTP:
  4321. { // User TFFS IOCTL - IOCTL_TFFS_BDTL_HW_PROTECTION
  4322. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_OTP\n"));
  4323. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4324. sizeof(UserOtpOutput)) ||
  4325. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4326. sizeof(UserOtpInput))) {
  4327. status = STATUS_INVALID_PARAMETER;
  4328. irp->IoStatus.Information = 0;
  4329. }
  4330. else {
  4331. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_OTP Start\n"));
  4332. userInput = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4333. userOutput = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4334. otpInput.type = ((UserOtpInput *)userInput)->type;
  4335. if(otpInput.type != OTP_SIZE){
  4336. otpInput.length = ((UserOtpInput *)userInput)->length;
  4337. if(otpInput.type != OTP_WRITE_LOCK)
  4338. otpInput.usedSize = ((UserOtpInput *)userInput)->usedSize;
  4339. }
  4340. //Updating OTP i/o buffer
  4341. if(otpInput.type == OTP_WRITE_LOCK)
  4342. otpInput.buffer = ((UserOtpInput *)userInput)->buffer;
  4343. else
  4344. otpInput.buffer = ((UserOtpOutput *)userOutput)->buffer;
  4345. ioreq.irHandle = deviceExtension->UnitNumber;
  4346. ioreq.irFlags = FL_IOCTL_OTP;
  4347. ioreq.irData = &flIoctlRec;
  4348. flIoctlRec.inputRecord = (VOID *)&otpInput;
  4349. flIoctlRec.outputRecord = (VOID *)(&(((UserOtpOutput *)userOutput)->statusRec));
  4350. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_OTP before flioctl\n"));
  4351. tffsStatus = flIOctl(&ioreq);
  4352. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_OTP after flioctl\n"));
  4353. if( tffsStatus == flOK ) {
  4354. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_OTP FLOK\n"));
  4355. irp->IoStatus.Information = sizeof(UserOtpInput);
  4356. status = STATUS_SUCCESS;
  4357. if(otpInput.type == OTP_SIZE){
  4358. ((UserOtpOutput *)userOutput)->length = otpInput.length;
  4359. ((UserOtpOutput *)userOutput)->usedSize = otpInput.usedSize;
  4360. ((UserOtpOutput *)userOutput)->lockedFlag = otpInput.lockedFlag;
  4361. ((UserOtpOutput *)userOutput)->statusRec.status = tffsStatus;
  4362. }
  4363. }
  4364. else {
  4365. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_OTP Failed!\n"));
  4366. irp->IoStatus.Information = 0;
  4367. status = STATUS_UNSUCCESSFUL;
  4368. }
  4369. }
  4370. userInput = NULL;
  4371. userOutput = NULL;
  4372. irp->IoStatus.Status = status;
  4373. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4374. continue;
  4375. }
  4376. #endif /* HW_OTP*/
  4377. case IOCTL_TFFS_DEEP_POWER_DOWN_MODE:
  4378. { // User TFFS IOCTL - IOCTL_TFFSFL_INQUIRE_CAPABILITIES
  4379. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: FL_IOCTL_DEEP_POWER_DOWN_MODE\n"));
  4380. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4381. sizeof(flOutputStatusRecord)) ||
  4382. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4383. sizeof(flPowerDownInput))) {
  4384. status = STATUS_INVALID_PARAMETER;
  4385. irp->IoStatus.Information = 0;
  4386. }
  4387. else {
  4388. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_DEEP_POWER_DOWN_MODE Start\n"));
  4389. ioreq.irHandle = deviceExtension->UnitNumber;
  4390. ioreq.irFlags = FL_IOCTL_DEEP_POWER_DOWN_MODE;
  4391. ioreq.irData = &flIoctlRec;
  4392. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4393. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4394. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_DEEP_POWER_DOWN_MODE before flioctl\n"));
  4395. tffsStatus = flIOctl(&ioreq);
  4396. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_DEEP_POWER_DOWN_MODE after flioctl\n"));
  4397. if( tffsStatus == flOK ) {
  4398. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_DEEP_POWER_DOWN_MODE FLOK\n"));
  4399. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4400. status = STATUS_SUCCESS;
  4401. }
  4402. else {
  4403. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_DEEP_POWER_DOWN_MODE Failed!\n"));
  4404. irp->IoStatus.Information = 0;
  4405. status = STATUS_UNSUCCESSFUL;
  4406. }
  4407. }
  4408. irp->IoStatus.Status = status;
  4409. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4410. continue;
  4411. }
  4412. case IOCTL_TFFSFL_INQUIRE_CAPABILITIES:
  4413. { // User TFFS IOCTL - IOCTL_TFFSFL_INQUIRE_CAPABILITIES
  4414. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: FL_IOCTL_UNIQUE_ID \n"));
  4415. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4416. sizeof(flCapabilityOutput)) ||
  4417. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4418. sizeof(flCapabilityInput))) {
  4419. status = STATUS_INVALID_PARAMETER;
  4420. irp->IoStatus.Information = 0;
  4421. }
  4422. else {
  4423. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_INQUIRE_CAPABILITIES Start\n"));
  4424. ioreq.irHandle = deviceExtension->UnitNumber;
  4425. ioreq.irFlags = FL_IOCTL_INQUIRE_CAPABILITIES;
  4426. ioreq.irData = &flIoctlRec;
  4427. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4428. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4429. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_INQUIRE_CAPABILITIES before flioctl\n"));
  4430. tffsStatus = flIOctl(&ioreq);
  4431. //tffsStatus = flOK;
  4432. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_INQUIRE_CAPABILITIES after flioctl\n"));
  4433. if( tffsStatus == flOK ) {
  4434. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_INQUIRE_CAPABILITIES FLOK\n"));
  4435. irp->IoStatus.Information = sizeof(flCapabilityInput);
  4436. status = STATUS_SUCCESS;
  4437. }
  4438. else {
  4439. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_INQUIRE_CAPABILITIES Failed!\n"));
  4440. irp->IoStatus.Information = 0;
  4441. status = STATUS_UNSUCCESSFUL;
  4442. }
  4443. }
  4444. irp->IoStatus.Status = status;
  4445. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4446. continue;
  4447. }
  4448. case IOCTL_TFFS_GET_INFO: { // User TFFS IOCTL - FL_GET_INFO
  4449. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsGetInfo\n"));
  4450. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4451. sizeof(flDiskInfoOutput)) {
  4452. status = STATUS_INVALID_PARAMETER;
  4453. irp->IoStatus.Information = 0;
  4454. }
  4455. else {
  4456. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo start get info\n"));
  4457. ioreq.irHandle = deviceExtension->UnitNumber;
  4458. ioreq.irFlags = FL_IOCTL_GET_INFO;
  4459. ioreq.irData = &flIoctlRec;
  4460. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4461. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo before flioctl\n"));
  4462. tffsStatus = flIOctl(&ioreq);
  4463. //tffsStatus = flOK;
  4464. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo after flioctl\n"));
  4465. if( tffsStatus == flOK ) {
  4466. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo FLOK\n"));
  4467. irp->IoStatus.Information = sizeof(flDiskInfoOutput);
  4468. status = STATUS_SUCCESS;
  4469. }
  4470. else {
  4471. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : TffsGetInfo !FLOK!\n"));
  4472. irp->IoStatus.Information = 0;
  4473. status = STATUS_UNSUCCESSFUL;
  4474. }
  4475. }
  4476. irp->IoStatus.Status = status;
  4477. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4478. continue;
  4479. }
  4480. case IOCTL_TFFS_DEFRAGMENT: { // User TFFS IOCTL - FL_DEFRAGMENT
  4481. flDefragInput iDefrag;
  4482. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsDefragment\n"));
  4483. if( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4484. sizeof(flDefragOutput)) {
  4485. status = STATUS_INVALID_PARAMETER;
  4486. irp->IoStatus.Information = 0;
  4487. }
  4488. else {
  4489. if( irpSp->Parameters.DeviceIoControl.InputBufferLength == 0 )
  4490. iDefrag.requiredNoOfSectors = -1;
  4491. else
  4492. iDefrag.requiredNoOfSectors = *((LONG *)(irp->AssociatedIrp.SystemBuffer));
  4493. ioreq.irHandle = deviceExtension->UnitNumber;
  4494. ioreq.irFlags = FL_IOCTL_DEFRAGMENT;
  4495. ioreq.irData = &flIoctlRec;
  4496. flIoctlRec.inputRecord = (VOID *)&iDefrag;
  4497. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4498. tffsStatus = flIOctl(&ioreq);
  4499. //tffsStatus = flOK;
  4500. if( tffsStatus == flOK ) {
  4501. irp->IoStatus.Information = sizeof(flDefragOutput);
  4502. status = STATUS_SUCCESS;
  4503. }
  4504. else {
  4505. irp->IoStatus.Information = 0;
  4506. status = STATUS_UNSUCCESSFUL;
  4507. }
  4508. }
  4509. irp->IoStatus.Status = status;
  4510. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4511. continue;
  4512. }
  4513. case IOCTL_TFFS_WRITE_PROTECT: { // User TFFS IOCTL - FL_WRITE_PROTECT
  4514. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsWriteProtect\n"));
  4515. if( irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4516. sizeof(flWriteProtectInput)) {
  4517. status = STATUS_INVALID_PARAMETER;
  4518. irp->IoStatus.Information = 0;
  4519. }
  4520. else {
  4521. ioreq.irHandle = deviceExtension->UnitNumber;
  4522. ioreq.irFlags = FL_IOCTL_WRITE_PROTECT;
  4523. ioreq.irData = &flIoctlRec;
  4524. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4525. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4526. tffsStatus = flIOctl(&ioreq);
  4527. if( tffsStatus == flOK ) {
  4528. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4529. status = STATUS_SUCCESS;
  4530. //Handling Enable and disable of write portected media
  4531. if(((flWriteProtectInput *)flIoctlRec.inputRecord)->type == FL_PROTECT){
  4532. deviceExtension->IsSWWriteProtected = TRUE;
  4533. }
  4534. else if(((flWriteProtectInput *)flIoctlRec.inputRecord)->type == FL_UNPROTECT){
  4535. deviceExtension->IsSWWriteProtected = FALSE;
  4536. }
  4537. else if(((flWriteProtectInput *)flIoctlRec.inputRecord)->type == FL_UNLOCK){
  4538. deviceExtension->IsSWWriteProtected = FALSE;
  4539. }
  4540. }
  4541. else {
  4542. irp->IoStatus.Information = 0;
  4543. status = STATUS_UNSUCCESSFUL;
  4544. }
  4545. }
  4546. irp->IoStatus.Status = status;
  4547. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4548. continue;
  4549. }
  4550. case IOCTL_TFFS_MOUNT_VOLUME: // User TFFS IOCTL - FL_MOUNT_VOLUME
  4551. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsMountVolume\n"));
  4552. if( (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4553. sizeof(flMountInput)) ||
  4554. (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4555. sizeof(flOutputStatusRecord)) ) {
  4556. status = STATUS_INVALID_PARAMETER;
  4557. irp->IoStatus.Information = 0;
  4558. }
  4559. else {
  4560. ioreq.irHandle = deviceExtension->UnitNumber;
  4561. ioreq.irFlags = FL_IOCTL_MOUNT_VOLUME;
  4562. ioreq.irData = &flIoctlRec;
  4563. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4564. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4565. tffsStatus = flIOctl(&ioreq);
  4566. if( tffsStatus == flOK ) {
  4567. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4568. status = STATUS_SUCCESS;
  4569. }
  4570. else {
  4571. irp->IoStatus.Information = 0;
  4572. status = STATUS_UNSUCCESSFUL;
  4573. }
  4574. }
  4575. irp->IoStatus.Status = status;
  4576. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4577. continue;
  4578. case IOCTL_TFFS_FORMAT_VOLUME: // User TFFS IOCTL - FL_FORMAT_VOLUME
  4579. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsFormatVolume\n"));
  4580. if( (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4581. sizeof(flFormatInput)) ||
  4582. (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4583. sizeof(flOutputStatusRecord)) ) {
  4584. status = STATUS_INVALID_PARAMETER;
  4585. irp->IoStatus.Information = 0;
  4586. }
  4587. else {
  4588. ioreq.irHandle = deviceExtension->UnitNumber;
  4589. ioreq.irFlags = FL_IOCTL_FORMAT_VOLUME;
  4590. ioreq.irData = &flIoctlRec;
  4591. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4592. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4593. tffsStatus = flIOctl(&ioreq);
  4594. if( tffsStatus == flOK ) {
  4595. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4596. status = STATUS_SUCCESS;
  4597. }
  4598. else {
  4599. irp->IoStatus.Information = 0;
  4600. status = STATUS_UNSUCCESSFUL;
  4601. }
  4602. }
  4603. irp->IoStatus.Status = status;
  4604. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4605. continue;
  4606. case IOCTL_TFFS_BDK_OPERATION:
  4607. { // User TFFS IOCTL - IOCTL_TFFSFL_INQUIRE_CAPABILITIES
  4608. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: IOCTL_TFFS_BDK_OPERATION\n"));
  4609. if( (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  4610. sizeof(flUserBDKOperationOutput)) ||
  4611. (irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4612. sizeof(flUserBDKOperationInput))) {
  4613. status = STATUS_INVALID_PARAMETER;
  4614. irp->IoStatus.Information = 0;
  4615. }
  4616. else {
  4617. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : FL_IOCTL_DEEP_POWER_DOWN_MODE Start\n"));
  4618. userInput = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4619. userOutput = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4620. bdkOperationInput.type = ((flUserBDKOperationInput *)userInput)->type;
  4621. //Copy new and old signature
  4622. for(i = 0; i < BDK_SIGNATURE_NAME; i++){
  4623. bdkOperationInput.bdkStruct.oldSign[i] = ((flUserBDKOperationInput *)userInput)->bdkStruct.oldSign[i];
  4624. bdkOperationInput.bdkStruct.newSign[i] = ((flUserBDKOperationInput *)userInput)->bdkStruct.newSign[i];
  4625. }
  4626. bdkOperationInput.bdkStruct.signOffset = ((flUserBDKOperationInput *)userInput)->bdkStruct.signOffset;
  4627. bdkOperationInput.bdkStruct.startingBlock = ((flUserBDKOperationInput *)userInput)->bdkStruct.startingBlock;
  4628. bdkOperationInput.bdkStruct.length = ((flUserBDKOperationInput *)userInput)->bdkStruct.length;
  4629. bdkOperationInput.bdkStruct.flags = ((flUserBDKOperationInput *)userInput)->bdkStruct.flags;
  4630. if(bdkOperationInput.type != BDK_READ)
  4631. bdkOperationInput.bdkStruct.bdkBuffer = ((flUserBDKOperationInput *)userInput)->bdkStruct.bdkBuffer;
  4632. else
  4633. bdkOperationInput.bdkStruct.bdkBuffer = ((flUserBDKOperationOutput *)userOutput)->bdkStruct.bdkBuffer;
  4634. ioreq.irHandle = (deviceExtension->UnitNumber & 0x0f) + (((flUserBDKOperationInput *)userOutput)->partitionNumber << 4);
  4635. ioreq.irFlags = FL_IOCTL_BDK_OPERATION;
  4636. ioreq.irData = &flIoctlRec;
  4637. flIoctlRec.inputRecord = &bdkOperationInput;
  4638. flIoctlRec.outputRecord = (VOID *) (&(((flUserBDKOperationOutput *)userOutput)->statusRec));
  4639. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDK_OPERATION before flioctl\n"));
  4640. tffsStatus = flIOctl(&ioreq);
  4641. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDK_OPERATION after flioctl\n"));
  4642. if( tffsStatus == flOK ) {
  4643. if(bdkOperationInput.type == BDK_GET_INFO){
  4644. ((flUserBDKOperationOutput *)userOutput)->bdkStruct.signOffset = bdkOperationInput.bdkStruct.signOffset;
  4645. ((flUserBDKOperationOutput *)userOutput)->bdkStruct.startingBlock = bdkOperationInput.bdkStruct.startingBlock;
  4646. ((flUserBDKOperationOutput *)userOutput)->bdkStruct.length = bdkOperationInput.bdkStruct.length;
  4647. ((flUserBDKOperationOutput *)userOutput)->bdkStruct.flags = bdkOperationInput.bdkStruct.flags;
  4648. }
  4649. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDK_OPERATION FLOK\n"));
  4650. irp->IoStatus.Information = sizeof(flUserBDKOperationOutput);
  4651. status = STATUS_SUCCESS;
  4652. }
  4653. else {
  4654. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: : IOCTL_TFFS_BDK_OPERATION Failed!\n"));
  4655. irp->IoStatus.Information = 0;
  4656. status = STATUS_UNSUCCESSFUL;
  4657. }
  4658. }
  4659. irp->IoStatus.Status = status;
  4660. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4661. continue;
  4662. }
  4663. case IOCTL_TFFS_DELETE_SECTORS: // User TFFS IOCTL - FL_DELETE_SECTORS
  4664. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: DeviceControl: TffsDeleteSectors\n"));
  4665. if( irpSp->Parameters.DeviceIoControl.InputBufferLength <
  4666. sizeof(flDeleteSectorsInput) ) {
  4667. status = STATUS_INVALID_PARAMETER;
  4668. irp->IoStatus.Information = 0;
  4669. }
  4670. else {
  4671. ioreq.irHandle = deviceExtension->UnitNumber;
  4672. ioreq.irFlags = FL_IOCTL_DELETE_SECTORS;
  4673. ioreq.irData = &flIoctlRec;
  4674. flIoctlRec.inputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4675. flIoctlRec.outputRecord = (VOID *)(irp->AssociatedIrp.SystemBuffer);
  4676. tffsStatus = flIOctl(&ioreq);
  4677. if( tffsStatus == flOK ) {
  4678. irp->IoStatus.Information = sizeof(flOutputStatusRecord);
  4679. status = STATUS_SUCCESS;
  4680. }
  4681. else {
  4682. irp->IoStatus.Information = 0;
  4683. status = STATUS_UNSUCCESSFUL;
  4684. }
  4685. }
  4686. irp->IoStatus.Status = status;
  4687. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4688. continue;
  4689. }
  4690. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: SrbFunction %Xh Command %Xh Unit %Xh\n",Srb->Function, Srb->Cdb[0], deviceExtension->UnitNumber));
  4691. switch (Srb->Function) {
  4692. case SRB_FUNCTION_EXECUTE_SCSI:
  4693. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: ExecuteScsi\n"));
  4694. // Sanity check. Only one request can be outstanding on a
  4695. // controller.
  4696. if (deviceExtension->CurrentSrb) {
  4697. // Restore the srb->DataBuffer if necesary
  4698. if (irp->MdlAddress != NULL) {
  4699. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: Restoration of Srb->DataBuffer done\n"));
  4700. Srb->DataBuffer = storedSrbDataBuffer;
  4701. }
  4702. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartIo: Already have a request!\n"));
  4703. Srb->SrbStatus = SRB_STATUS_BUSY;
  4704. irp->IoStatus.Information = 0;
  4705. irp->IoStatus.Status = STATUS_DEVICE_BUSY;
  4706. IoCompleteRequest(irp,IO_NO_INCREMENT);
  4707. return;
  4708. }
  4709. // Indicate that a request is active
  4710. deviceExtension->CurrentSrb = Srb;
  4711. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Command %x to device %d\n",
  4712. Srb->Cdb[0],
  4713. Srb->TargetId));
  4714. switch (Srb->Cdb[0]) {
  4715. case SCSIOP_INQUIRY:
  4716. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Inquiry\n"));
  4717. if (Srb->Lun != 0 || Srb->TargetId != 0) {
  4718. status = SRB_STATUS_SELECTION_TIMEOUT;
  4719. break;
  4720. } else {
  4721. PINQUIRYDATA inquiryData = Srb->DataBuffer;
  4722. if (transferForbidden) {
  4723. status = SRB_STATUS_ERROR;
  4724. break;
  4725. }
  4726. // Zero INQUIRY data structure.
  4727. for (i = 0; i < Srb->DataTransferLength; i++) {
  4728. ((PUCHAR)Srb->DataBuffer)[i] = 0;
  4729. }
  4730. inquiryData->DeviceType = deviceExtension->ScsiDeviceType;
  4731. if (deviceExtension->removableMedia) {
  4732. inquiryData->RemovableMedia = 1;
  4733. }
  4734. for (i = 0; i < 8; i++)
  4735. inquiryData->VendorId[i] = vendorString[i];
  4736. for (i = 0; i < 16; i++)
  4737. inquiryData->ProductId[i] = productString[i];
  4738. for (i = 0; i < 4; i++)
  4739. inquiryData->ProductRevisionLevel[i] = revisionString[i];
  4740. status = SRB_STATUS_SUCCESS;
  4741. }
  4742. break;
  4743. case SCSIOP_MODE_SENSE:
  4744. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: ModeSense\n"));
  4745. cdb = (PCDB) Srb->Cdb;
  4746. if ((cdb->MODE_SENSE.PageCode != MODE_SENSE_RETURN_ALL) ||
  4747. (cdb->MODE_SENSE.AllocationLength != MODE_DATA_SIZE )) {
  4748. status = SRB_STATUS_INVALID_REQUEST;
  4749. break;
  4750. }
  4751. if (transferForbidden) {
  4752. status = SRB_STATUS_ERROR;
  4753. break;
  4754. }
  4755. // Set mode page data(only a geometry) for DISK class driver.
  4756. // DISK class driver get the geometry of all media(scsi ata) by mode sense.
  4757. pageData = Srb->DataBuffer;
  4758. ((PMODE_PARAMETER_HEADER) pageData)->ModeDataLength = MODE_DATA_SIZE;
  4759. parameterHeaderLength = sizeof(MODE_PARAMETER_HEADER);
  4760. blockDescriptorLength = ((PMODE_PARAMETER_HEADER) pageData)->BlockDescriptorLength = 0x8;
  4761. pageData += parameterHeaderLength + blockDescriptorLength;
  4762. // MODE_PAGE_ERROR_RECOVERY data.
  4763. ((PMODE_DISCONNECT_PAGE) pageData)->PageCode = MODE_PAGE_ERROR_RECOVERY;
  4764. ((PMODE_DISCONNECT_PAGE) pageData)->PageLength = 0x6;
  4765. // Advance to the next page.
  4766. pageData += ((PMODE_DISCONNECT_PAGE) pageData)->PageLength + 2;
  4767. // MODE_PAGE_FORMAT_DEVICE data set.
  4768. ((PMODE_DISCONNECT_PAGE) pageData)->PageCode = MODE_PAGE_FORMAT_DEVICE;
  4769. ((PMODE_DISCONNECT_PAGE) pageData)->PageLength = 0x16;
  4770. // SectorsPerTrack
  4771. ((PFOUR_BYTE)&((PMODE_FORMAT_PAGE) pageData)->SectorsPerTrack[0])->Byte1
  4772. = ((PFOUR_BYTE)&deviceExtension->SectorsPerTrack)->Byte0;
  4773. ((PFOUR_BYTE)&((PMODE_FORMAT_PAGE) pageData)->SectorsPerTrack[0])->Byte0
  4774. = ((PFOUR_BYTE)&deviceExtension->SectorsPerTrack)->Byte1;
  4775. // Advance to the next page.
  4776. pageData += ((PMODE_DISCONNECT_PAGE) pageData)->PageLength + 2;
  4777. // MODE_PAGE_RIGID_GEOMETRY data set.
  4778. ((PMODE_DISCONNECT_PAGE) pageData)->PageCode = MODE_PAGE_RIGID_GEOMETRY;
  4779. ((PMODE_DISCONNECT_PAGE) pageData)->PageLength = 0x12;
  4780. // NumberOfHeads
  4781. ((PMODE_RIGID_GEOMETRY_PAGE) pageData)->NumberOfHeads
  4782. = (UCHAR)deviceExtension->NumberOfHeads;
  4783. // NumberOfCylindersfahjbbjknz
  4784. ((PFOUR_BYTE)&((PMODE_RIGID_GEOMETRY_PAGE) pageData)->NumberOfCylinders)->Byte2
  4785. = ((PFOUR_BYTE)&deviceExtension->Cylinders)->Byte0;
  4786. ((PFOUR_BYTE)&((PMODE_RIGID_GEOMETRY_PAGE) pageData)->NumberOfCylinders)->Byte1
  4787. = ((PFOUR_BYTE)&deviceExtension->Cylinders)->Byte1;
  4788. ((PFOUR_BYTE)&((PMODE_RIGID_GEOMETRY_PAGE) pageData)->NumberOfCylinders)->Byte0
  4789. = ((PFOUR_BYTE)&deviceExtension->Cylinders)->Byte2;
  4790. Srb->DataTransferLength = MODE_DATA_SIZE;
  4791. status = SRB_STATUS_SUCCESS;
  4792. break;
  4793. case SCSIOP_TEST_UNIT_READY:
  4794. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: TestUnitReady\n"));
  4795. status = SRB_STATUS_SUCCESS;
  4796. break;
  4797. case SCSIOP_READ_CAPACITY:
  4798. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: ReadCapacity\n"));
  4799. if (transferForbidden) {
  4800. status = SRB_STATUS_ERROR;
  4801. break;
  4802. }
  4803. // Claim 512 byte blocks (big-endian).
  4804. ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
  4805. // Calculate last sector.
  4806. i = deviceExtension->totalSectors - 1;
  4807. ((PFOUR_BYTE)& ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress)->Byte0 =
  4808. ((PFOUR_BYTE)&i)->Byte3;
  4809. ((PFOUR_BYTE)& ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress)->Byte1 =
  4810. ((PFOUR_BYTE)&i)->Byte2;
  4811. ((PFOUR_BYTE)& ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress)->Byte2 =
  4812. ((PFOUR_BYTE)&i)->Byte1;
  4813. ((PFOUR_BYTE)& ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress)->Byte3 =
  4814. ((PFOUR_BYTE)&i)->Byte0;
  4815. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: DiskOnChip %x - #sectors %x, #heads %x, #cylinders %x #total %x\n",
  4816. Srb->TargetId,
  4817. deviceExtension->SectorsPerTrack,
  4818. deviceExtension->NumberOfHeads,
  4819. deviceExtension->Cylinders,
  4820. i));
  4821. status = SRB_STATUS_SUCCESS;
  4822. break;
  4823. case SCSIOP_VERIFY:
  4824. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Verify\n"));
  4825. status = SRB_STATUS_SUCCESS;
  4826. break;
  4827. case SCSIOP_READ:
  4828. case SCSIOP_WRITE:
  4829. deviceExtension->DataBuffer = (PUSHORT)Srb->DataBuffer;
  4830. startingSector = ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte3 |
  4831. ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte2 << 8 |
  4832. ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 |
  4833. ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24;
  4834. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: ReadWrite: Starting sector is %x, Number of bytes %x\n",startingSector,Srb->DataTransferLength));
  4835. if (transferForbidden) {
  4836. status = SRB_STATUS_ERROR;
  4837. break;
  4838. }
  4839. ioreq.irHandle = deviceExtension->UnitNumber;
  4840. ioreq.irSectorNo = startingSector;
  4841. ioreq.irSectorCount = Srb->DataTransferLength >> SECTOR_SIZE_BITS;
  4842. ioreq.irData = deviceExtension->DataBuffer;
  4843. if (startingSector >= deviceExtension->totalSectors) {
  4844. tffsStatus = flSectorNotFound;
  4845. }
  4846. else {
  4847. if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
  4848. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Read\n"));
  4849. if(deviceExtension->IsWriteProtected && deviceExtension->IsPartitonTableWritten && (ioreq.irSectorNo == 0)){
  4850. tffscpy(deviceExtension->DataBuffer, deviceExtension->PartitonTable, sizeof(deviceExtension->PartitonTable));
  4851. tffsStatus = flOK;
  4852. status = (UCHAR)(tffsStatus == flOK) ? SRB_STATUS_SUCCESS : SRB_STATUS_ERROR;
  4853. }
  4854. else{
  4855. tffsStatus = flAbsRead(&ioreq);
  4856. if (irp->MdlAddress) {
  4857. KeFlushIoBuffers(irp->MdlAddress, TRUE, FALSE);
  4858. }
  4859. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Read status %Xh\n", tffsStatus));
  4860. status = (UCHAR)(tffsStatus == flOK) ? SRB_STATUS_SUCCESS : SRB_STATUS_ERROR;
  4861. }
  4862. }
  4863. else {
  4864. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Write\n"));
  4865. //Handle partiton table - simulate write to sector 0 (Volume Manager signature - write it to buffer in RAM) only once.
  4866. if((deviceExtension->IsWriteProtected || deviceExtension->IsSWWriteProtected) && (ioreq.irSectorNo == 0) && (deviceExtension->IsPartitonTableWritten == FALSE)){
  4867. tffscpy(deviceExtension->PartitonTable, deviceExtension->DataBuffer, sizeof(deviceExtension->PartitonTable));
  4868. deviceExtension->IsPartitonTableWritten = TRUE;
  4869. status = tffsStatus = STATUS_MEDIA_WRITE_PROTECTED;
  4870. //tffsStatus = flOK;
  4871. //status = SRB_STATUS_SUCCESS;
  4872. }//In case of writing to Write Protected Device
  4873. else if(deviceExtension->IsWriteProtected || deviceExtension->IsSWWriteProtected){
  4874. status = tffsStatus = STATUS_MEDIA_WRITE_PROTECTED;
  4875. }
  4876. else{
  4877. tffsStatus = flAbsWrite(&ioreq);
  4878. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Write status %Xh\n", tffsStatus));
  4879. //For the first time trying to write to SW protected media
  4880. if(tffsStatus==flWriteProtect){
  4881. deviceExtension->IsSWWriteProtected = TRUE;
  4882. if((ioreq.irSectorNo == 0) && (deviceExtension->IsPartitonTableWritten == FALSE)){
  4883. tffscpy(deviceExtension->PartitonTable, deviceExtension->DataBuffer, sizeof(deviceExtension->PartitonTable));
  4884. deviceExtension->IsPartitonTableWritten = TRUE;
  4885. }
  4886. status = tffsStatus = STATUS_MEDIA_WRITE_PROTECTED;
  4887. }
  4888. else
  4889. {
  4890. //status = (UCHAR)(tffsStatus == flOK) ? SRB_STATUS_SUCCESS : SRB_STATUS_ERROR;
  4891. if(tffsStatus==flOK)
  4892. status = SRB_STATUS_SUCCESS;
  4893. else
  4894. status = SRB_STATUS_ERROR;
  4895. }
  4896. }
  4897. }
  4898. }
  4899. //TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: ReadWrite status %Xh\n", tffsStatus));
  4900. //status = (UCHAR)(tffsStatus == flOK) ? SRB_STATUS_SUCCESS : SRB_STATUS_ERROR;
  4901. break;
  4902. case SCSIOP_START_STOP_UNIT:
  4903. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: StartStopUnit\n"));
  4904. status = SRB_STATUS_SUCCESS;
  4905. break;
  4906. case SCSIOP_REQUEST_SENSE:
  4907. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: RequestSense\n"));
  4908. // this function makes sense buffers to report the results
  4909. // of the original GET_MEDIA_STATUS command
  4910. // status = SRB_STATUS_SUCCESS;
  4911. break;
  4912. default:
  4913. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: StartIo: Unsupported command %Xh\n",Srb->Cdb[0]));
  4914. status = SRB_STATUS_INVALID_REQUEST;
  4915. } // end switch
  4916. break;
  4917. case SRB_FUNCTION_ABORT_COMMAND:
  4918. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: AbortCommand\n"));
  4919. // Verify that SRB to abort is still outstanding.
  4920. if (!deviceExtension->CurrentSrb) {
  4921. TffsDebugPrint((TFFS_DEB_ERROR,"Trueffs: StartIo: SRB to abort already completed\n"));
  4922. status = SRB_STATUS_ABORT_FAILED;
  4923. break;
  4924. }
  4925. case SRB_FUNCTION_RESET_BUS:
  4926. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Reset bus request received\n"));
  4927. status = SRB_STATUS_SUCCESS;
  4928. break;
  4929. default:
  4930. // Indicate unsupported command.
  4931. TffsDebugPrint((TFFS_DEB_WARN,"Trueffs: StartIo: unsupported function\n"));
  4932. status = SRB_STATUS_INVALID_REQUEST;
  4933. break;
  4934. } // end switch
  4935. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: StartIo: Srb %Xh complete with status %Xh\n", Srb, status));
  4936. // Clear current SRB.
  4937. deviceExtension->CurrentSrb = NULL;
  4938. Srb->SrbStatus = (UCHAR)status;
  4939. if (status == SRB_STATUS_SUCCESS) {
  4940. irp->IoStatus.Information = Srb->DataTransferLength;
  4941. }
  4942. else {
  4943. irp->IoStatus.Information = 0;
  4944. }
  4945. // Restore the srb->DataBuffer if necesary
  4946. if (irp->MdlAddress != NULL) {
  4947. TffsDebugPrint((TFFS_DEB_INFO, "Trueffs: Restoration of Srb->DataBuffer done\n"));
  4948. Srb->DataBuffer = storedSrbDataBuffer;
  4949. }
  4950. irp->IoStatus.Status = TrueffsTranslateSRBStatus(status);
  4951. IoCompleteRequest( irp, IO_DISK_INCREMENT );
  4952. } // while there's packets to process
  4953. } while ( TRUE );
  4954. }
  4955. NTSTATUS
  4956. QueueIrpToThread(
  4957. IN OUT PIRP Irp,
  4958. IN OUT PDEVICE_EXTENSION deviceExtension
  4959. )
  4960. /*++
  4961. Routine Description:
  4962. This routine queues the given irp to be serviced by the Trueffs
  4963. thread. If the thread is down then this routine creates the thread.
  4964. Arguments:
  4965. Irp - Supplies the IRP to queue to the thread.
  4966. Return Value:
  4967. May return an error if PsCreateSystemThread fails.
  4968. Otherwise returns STATUS_PENDING and marks the IRP pending.
  4969. --*/
  4970. {
  4971. NTSTATUS status;
  4972. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: QueueIrpToThread\n"));
  4973. IoMarkIrpPending(Irp);
  4974. ExInterlockedInsertTailList(&deviceExtension->listEntry,&Irp->Tail.Overlay.ListEntry,&deviceExtension->listSpinLock);
  4975. if (!KeReadStateSemaphore(&deviceExtension->requestSemaphore)) {
  4976. KeReleaseSemaphore(&deviceExtension->requestSemaphore,(KPRIORITY) 0,1,FALSE);
  4977. }
  4978. TffsDebugPrint((TFFS_DEB_INFO,"Trueffs: QueueIrpToThread: Irp %Xh queued\n", Irp));
  4979. return STATUS_PENDING;
  4980. }
  4981. NTSTATUS
  4982. TrueffsTranslateSRBStatus(
  4983. ULONG status
  4984. )
  4985. /*++
  4986. Routine Description:
  4987. This routine translates an srb status into an ntstatus.
  4988. Arguments:
  4989. SRB status
  4990. Return Value:
  4991. An nt status approprate for the error.
  4992. --*/
  4993. {
  4994. switch (status) {
  4995. case SRB_STATUS_INTERNAL_ERROR:
  4996. return(STATUS_MEDIA_WRITE_PROTECTED); //(STATUS_WMI_READ_ONLY);
  4997. case SRB_STATUS_SELECTION_TIMEOUT:
  4998. return(STATUS_DEVICE_NOT_CONNECTED);
  4999. case SRB_STATUS_SUCCESS:
  5000. return (STATUS_SUCCESS);
  5001. case SRB_STATUS_INVALID_REQUEST:
  5002. return(STATUS_INVALID_DEVICE_REQUEST);
  5003. case SRB_STATUS_ABORT_FAILED:
  5004. default:
  5005. return(STATUS_DISK_OPERATION_FAILED);
  5006. }
  5007. return(STATUS_DISK_OPERATION_FAILED);
  5008. }
  5009. NTSTATUS
  5010. TrueffsDeviceQueryId(
  5011. IN PDEVICE_OBJECT DeviceObject,
  5012. IN OUT PIRP Irp,
  5013. BOOLEAN Fdo
  5014. )
  5015. {
  5016. PIO_STACK_LOCATION thisIrpSp = IoGetCurrentIrpStackLocation(Irp);
  5017. PDEVICE_EXTENSION deviceExtension;
  5018. PWSTR idString = NULL;
  5019. BOOLEAN bHandled = TRUE;
  5020. NTSTATUS status;
  5021. if (Fdo)
  5022. {
  5023. deviceExtension = DeviceObject->DeviceExtension;
  5024. }
  5025. else
  5026. {
  5027. PPDO_EXTENSION pdoExtension = DeviceObject->DeviceExtension;
  5028. deviceExtension = pdoExtension->Pext;
  5029. }
  5030. switch (thisIrpSp->Parameters.QueryId.IdType)
  5031. {
  5032. case BusQueryDeviceID:
  5033. TffsDebugPrint ((TFFS_DEB_INFO, "Trueffs: QueryDeviceID\n"));
  5034. idString = DeviceBuildBusId(deviceExtension, Fdo);
  5035. break;
  5036. case BusQueryInstanceID:
  5037. TffsDebugPrint ((TFFS_DEB_INFO, "Trueffs: QueryInstanceID\n"));
  5038. idString = DeviceBuildInstanceId(deviceExtension, Fdo);
  5039. break;
  5040. case BusQueryCompatibleIDs:
  5041. TffsDebugPrint ((TFFS_DEB_INFO, "Trueffs: QueryCompatibleIDs\n"));
  5042. idString = DeviceBuildCompatibleId(deviceExtension, Fdo);
  5043. break;
  5044. case BusQueryHardwareIDs:
  5045. TffsDebugPrint ((TFFS_DEB_INFO, "Trueffs: QueryHardwareIDs\n"));
  5046. idString = DeviceBuildHardwareId(deviceExtension, Fdo);
  5047. break;
  5048. default:
  5049. //
  5050. // The PDO should complete this request without altering its status
  5051. //
  5052. status = Irp->IoStatus.Status;
  5053. bHandled = FALSE;
  5054. break;
  5055. }
  5056. if (bHandled)
  5057. {
  5058. if (idString == NULL)
  5059. {
  5060. status = STATUS_INSUFFICIENT_RESOURCES;
  5061. bHandled = FALSE;
  5062. }
  5063. }
  5064. if (bHandled)
  5065. {
  5066. if (Fdo)
  5067. {
  5068. //
  5069. // Forward this request down synchronously, in case a lower driver wants to handle it
  5070. //
  5071. IoCopyCurrentIrpStackLocationToNext(Irp);
  5072. status = TrueffsCallDriverSync(deviceExtension->LowerDeviceObject, Irp);
  5073. if (status == STATUS_NOT_SUPPORTED)
  5074. {
  5075. Irp->IoStatus.Information = (UINT_PTR) idString;
  5076. status = STATUS_SUCCESS;
  5077. }
  5078. else
  5079. {
  5080. //
  5081. // Someone lower down took care of this request
  5082. //
  5083. ExFreePool(idString);
  5084. }
  5085. }
  5086. else
  5087. {
  5088. Irp->IoStatus.Information = (UINT_PTR) idString;
  5089. status = STATUS_SUCCESS;
  5090. }
  5091. }
  5092. else
  5093. {
  5094. if (Fdo)
  5095. {
  5096. //
  5097. // Forward this request down synchronously, in case a lower driver understands it
  5098. //
  5099. IoCopyCurrentIrpStackLocationToNext(Irp);
  5100. status = TrueffsCallDriverSync(deviceExtension->LowerDeviceObject, Irp);
  5101. }
  5102. }
  5103. Irp->IoStatus.Status = status;
  5104. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  5105. return status;
  5106. }
  5107. PWSTR
  5108. DeviceBuildBusId(
  5109. IN PDEVICE_EXTENSION deviceExtension,
  5110. BOOLEAN Fdo
  5111. )
  5112. {
  5113. PUCHAR idString;
  5114. PCSTR compatibleIdString;
  5115. CCHAR compatibleId[10];
  5116. ULONG compatibleIdLen;
  5117. USHORT idStringBufLen;
  5118. NTSTATUS status;
  5119. UCHAR tffsBusIdFormat[] = "FlashMedia\\%s_%s_%s%s_%s";
  5120. PWCHAR typeString;
  5121. ANSI_STRING ansiBusIdString;
  5122. UNICODE_STRING unicodeIdString;
  5123. if (Fdo) {
  5124. compatibleIdString = TrueffsGetCompatibleIdStringFDO (
  5125. deviceExtension->ScsiDeviceType
  5126. );
  5127. }
  5128. else {
  5129. compatibleIdString = TrueffsGetCompatibleIdString (
  5130. deviceExtension->ScsiDeviceType
  5131. );
  5132. }
  5133. if (compatibleIdString == NULL) {
  5134. sprintf (compatibleId,
  5135. "Type%d",
  5136. deviceExtension->ScsiDeviceType);
  5137. compatibleIdString = compatibleId;
  5138. }
  5139. compatibleIdLen = strlen(compatibleIdString);
  5140. idStringBufLen = (USHORT) (( strlen( tffsBusIdFormat ) +
  5141. compatibleIdLen +
  5142. VENDORSTRINGSIZE +
  5143. PRODUCTSTRINGSIZE +
  5144. REVISIONSTRINGSIZE +
  5145. SERIALSTRINGSIZE +
  5146. 1) * sizeof( WCHAR ));
  5147. idString = ExAllocatePoolWithTag( PagedPool, idStringBufLen * 2, TFFSPORT_POOL_TAG);
  5148. if (idString){
  5149. sprintf (idString + idStringBufLen,
  5150. tffsBusIdFormat,
  5151. compatibleIdString,
  5152. VENDORSTRING,
  5153. PRODUCTSTRING,
  5154. REVISIONSTRING,
  5155. SERIALSTRING
  5156. );
  5157. RtlInitAnsiString (
  5158. &ansiBusIdString,
  5159. idString + idStringBufLen
  5160. );
  5161. unicodeIdString.Length = 0;
  5162. unicodeIdString.MaximumLength = idStringBufLen;
  5163. unicodeIdString.Buffer = (PWSTR) idString;
  5164. RtlAnsiStringToUnicodeString(
  5165. &unicodeIdString,
  5166. &ansiBusIdString,
  5167. FALSE
  5168. );
  5169. unicodeIdString.Buffer[unicodeIdString.Length/2 + 0] = L'\0';
  5170. }
  5171. return (PWSTR) idString;
  5172. }
  5173. PWSTR
  5174. DeviceBuildInstanceId(
  5175. IN PDEVICE_EXTENSION deviceExtension,
  5176. BOOLEAN Fdo
  5177. )
  5178. {
  5179. PWSTR idString;
  5180. ULONG idStringBufLen;
  5181. NTSTATUS status;
  5182. WCHAR tffsUniqueIdFormat[] = L"%x.%x.%x";
  5183. UCHAR firstId = 'A';
  5184. UCHAR secondId = 'G';
  5185. idStringBufLen = 50 * sizeof( WCHAR );
  5186. idString = ExAllocatePoolWithTag (PagedPool, idStringBufLen, TFFSPORT_POOL_TAG);
  5187. if( idString == NULL ){
  5188. return NULL;
  5189. }
  5190. // Form the string and return it.
  5191. swprintf( idString,
  5192. tffsUniqueIdFormat,
  5193. firstId,
  5194. secondId,
  5195. deviceExtension->TrueffsDeviceNumber);
  5196. return idString;
  5197. }
  5198. PWSTR
  5199. DeviceBuildCompatibleId(
  5200. IN PDEVICE_EXTENSION deviceExtension,
  5201. BOOLEAN Fdo
  5202. )
  5203. {
  5204. NTSTATUS status;
  5205. ULONG idStringBufLen;
  5206. PCSTR compatibleIdString;
  5207. ANSI_STRING ansiCompatibleIdString;
  5208. UNICODE_STRING unicodeIdString;
  5209. if (Fdo) {
  5210. compatibleIdString = TrueffsGetCompatibleIdStringFDO (deviceExtension->ScsiDeviceType);
  5211. }
  5212. else {
  5213. compatibleIdString = TrueffsGetCompatibleIdString (deviceExtension->ScsiDeviceType);
  5214. }
  5215. RtlInitAnsiString (
  5216. &ansiCompatibleIdString,
  5217. compatibleIdString
  5218. );
  5219. idStringBufLen = RtlAnsiStringToUnicodeSize (
  5220. &ansiCompatibleIdString
  5221. );
  5222. unicodeIdString.Length = 0;
  5223. unicodeIdString.MaximumLength = (USHORT) idStringBufLen;
  5224. idStringBufLen += 2 * sizeof (WCHAR);
  5225. unicodeIdString.Buffer = ExAllocatePoolWithTag (PagedPool, idStringBufLen, TFFSPORT_POOL_TAG);
  5226. if (unicodeIdString.Buffer) {
  5227. RtlAnsiStringToUnicodeString(
  5228. &unicodeIdString,
  5229. &ansiCompatibleIdString,
  5230. FALSE
  5231. );
  5232. unicodeIdString.Buffer[unicodeIdString.Length/2 + 0] = L'\0';
  5233. unicodeIdString.Buffer[unicodeIdString.Length/2 + 1] = L'\0';
  5234. }
  5235. return unicodeIdString.Buffer;
  5236. }
  5237. PWSTR
  5238. DeviceBuildHardwareId(
  5239. IN PDEVICE_EXTENSION deviceExtension,
  5240. BOOLEAN Fdo
  5241. )
  5242. {
  5243. #define NUMBER_HARDWARE_STRINGS 5
  5244. ULONG i;
  5245. PWSTR idMultiString;
  5246. PWSTR idString;
  5247. UCHAR scratch[64] = { 0 };
  5248. ULONG idStringLen;
  5249. NTSTATUS status;
  5250. ANSI_STRING ansiCompatibleIdString;
  5251. UNICODE_STRING unicodeIdString;
  5252. PCSTR deviceTypeCompIdString;
  5253. UCHAR deviceTypeCompId[20];
  5254. PCSTR deviceTypeIdString;
  5255. UCHAR deviceTypeId[20];
  5256. UCHAR ScsiDeviceType;
  5257. ScsiDeviceType = deviceExtension->ScsiDeviceType;
  5258. idStringLen = (64 * NUMBER_HARDWARE_STRINGS + sizeof (UCHAR)) * sizeof (WCHAR);
  5259. idMultiString = ExAllocatePoolWithTag (PagedPool, idStringLen, TFFSPORT_POOL_TAG);
  5260. if (idMultiString == NULL) {
  5261. return NULL;
  5262. }
  5263. if (Fdo) {
  5264. deviceTypeIdString = TrueffsGetDeviceTypeStringFDO(ScsiDeviceType);
  5265. }
  5266. else {
  5267. deviceTypeIdString = TrueffsGetDeviceTypeString(ScsiDeviceType);
  5268. }
  5269. if (deviceTypeIdString == NULL) {
  5270. sprintf (deviceTypeId,
  5271. "Type%d",
  5272. ScsiDeviceType);
  5273. deviceTypeIdString = deviceTypeId;
  5274. }
  5275. if (Fdo)
  5276. deviceTypeCompIdString = TrueffsGetCompatibleIdStringFDO (ScsiDeviceType);
  5277. else
  5278. deviceTypeCompIdString = TrueffsGetCompatibleIdString (ScsiDeviceType);
  5279. if (deviceTypeCompIdString == NULL) {
  5280. sprintf (deviceTypeCompId,
  5281. "GenType%d",
  5282. ScsiDeviceType);
  5283. deviceTypeCompIdString = deviceTypeCompId;
  5284. }
  5285. // Zero out the string buffer
  5286. RtlZeroMemory(idMultiString, idStringLen);
  5287. idString = idMultiString;
  5288. for(i = 0; i < NUMBER_HARDWARE_STRINGS; i++) {
  5289. // Build each of the hardware id's
  5290. switch(i) {
  5291. // Bus + Dev Type + Vendor + Product + Revision
  5292. case 0: {
  5293. sprintf(scratch, "FlashMedia\\%s", deviceTypeIdString);
  5294. CopyField(scratch + strlen(scratch),
  5295. VENDORSTRING,
  5296. VENDORSTRINGSIZE,
  5297. '_');
  5298. CopyField(scratch + strlen(scratch),
  5299. PRODUCTSTRING,
  5300. PRODUCTSTRINGSIZE,
  5301. '_');
  5302. CopyField(scratch + strlen(scratch),
  5303. REVISIONSTRING,
  5304. REVISIONSTRINGSIZE,
  5305. '_');
  5306. break;
  5307. }
  5308. // bus + vendor + product + revision[0]
  5309. case 1: {
  5310. sprintf(scratch, "FlashMedia\\");
  5311. CopyField(scratch + strlen(scratch),
  5312. VENDORSTRING,
  5313. VENDORSTRINGSIZE,
  5314. '_');
  5315. CopyField(scratch + strlen(scratch),
  5316. PRODUCTSTRING,
  5317. PRODUCTSTRINGSIZE,
  5318. '_');
  5319. CopyField(scratch + strlen(scratch),
  5320. REVISIONSTRING,
  5321. REVISIONSTRINGSIZE,
  5322. '_');
  5323. break;
  5324. }
  5325. // bus + device + vendor + product
  5326. case 2: {
  5327. sprintf(scratch, "FlashMedia\\%s", deviceTypeIdString);
  5328. CopyField(scratch + strlen(scratch),
  5329. VENDORSTRING,
  5330. VENDORSTRINGSIZE,
  5331. '_');
  5332. break;
  5333. }
  5334. // vendor + product + revision[0] (win9x)
  5335. case 3: {
  5336. CopyField(scratch,
  5337. VENDORSTRING,
  5338. VENDORSTRINGSIZE,
  5339. '_');
  5340. CopyField(scratch + strlen(scratch),
  5341. PRODUCTSTRING,
  5342. PRODUCTSTRINGSIZE,
  5343. '_');
  5344. CopyField(scratch + strlen(scratch),
  5345. REVISIONSTRING,
  5346. REVISIONSTRINGSIZE,
  5347. '_');
  5348. break;
  5349. }
  5350. case 4: {
  5351. strncpy(scratch, deviceTypeCompIdString, sizeof(scratch) - 1);
  5352. break;
  5353. }
  5354. default: {
  5355. break;
  5356. }
  5357. }
  5358. RtlInitAnsiString (
  5359. &ansiCompatibleIdString,
  5360. scratch
  5361. );
  5362. unicodeIdString.Length = 0;
  5363. unicodeIdString.MaximumLength = (USHORT) RtlAnsiStringToUnicodeSize(
  5364. &ansiCompatibleIdString
  5365. );
  5366. unicodeIdString.Buffer = idString;
  5367. RtlAnsiStringToUnicodeString(
  5368. &unicodeIdString,
  5369. &ansiCompatibleIdString,
  5370. FALSE
  5371. );
  5372. idString[unicodeIdString.Length / 2] = L'\0';
  5373. idString += unicodeIdString.Length / 2+ 1;
  5374. }
  5375. idString[0] = L'\0';
  5376. return idMultiString;
  5377. #undef NUMBER_HARDWARE_STRINGS
  5378. }
  5379. VOID
  5380. CopyField(
  5381. IN PUCHAR Destination,
  5382. IN PUCHAR Source,
  5383. IN ULONG Count,
  5384. IN UCHAR Change
  5385. )
  5386. /*++
  5387. Routine Description:
  5388. This routine will copy Count string bytes from Source to Destination. If
  5389. it finds a nul byte in the Source it will translate that and any subsequent
  5390. bytes into Change. It will also replace spaces with the specified character.
  5391. Arguments:
  5392. Destination - the location to copy bytes
  5393. Source - the location to copy bytes from
  5394. Count - the number of bytes to be copied
  5395. Return Value:
  5396. none
  5397. --*/
  5398. {
  5399. ULONG i = 0;
  5400. BOOLEAN pastEnd = FALSE;
  5401. for(i = 0; i < Count; i++) {
  5402. if(!pastEnd) {
  5403. if(Source[i] == 0) {
  5404. pastEnd = TRUE;
  5405. Destination[i] = Change;
  5406. } else if(Source[i] == L' ') {
  5407. Destination[i] = Change;
  5408. } else {
  5409. Destination[i] = Source[i];
  5410. }
  5411. } else {
  5412. Destination[i] = Change;
  5413. }
  5414. }
  5415. Destination[i] = L'\0';
  5416. return;
  5417. }
  5418. PCSTR
  5419. TrueffsGetDeviceTypeString (
  5420. IN ULONG DeviceType
  5421. )
  5422. /*++
  5423. Routine Description:
  5424. look up SCSI device type string
  5425. Arguments:
  5426. DeviceType - SCSI device type
  5427. Return Value:
  5428. device type string
  5429. --*/
  5430. {
  5431. if (DeviceType < (sizeof (TffsDeviceType_tffsport) / sizeof (TFFS_DEVICE_TYPE))) {
  5432. return TffsDeviceType_tffsport[DeviceType].DeviceTypeString;
  5433. } else {
  5434. return NULL;
  5435. }
  5436. }
  5437. PCSTR
  5438. TrueffsGetDeviceTypeStringFDO (
  5439. IN ULONG DeviceType
  5440. )
  5441. /*++
  5442. Routine Description:
  5443. look up SCSI device type string
  5444. Arguments:
  5445. DeviceType - SCSI device type
  5446. Return Value:
  5447. device type string
  5448. --*/
  5449. {
  5450. if (DeviceType < (sizeof (TffsDeviceType_tffsport) / sizeof (TFFS_DEVICE_TYPE))) {
  5451. return TffsDeviceTypeFDO_tffsport[DeviceType].DeviceTypeString;
  5452. } else {
  5453. return NULL;
  5454. }
  5455. }
  5456. PCSTR
  5457. TrueffsGetCompatibleIdString (
  5458. IN ULONG DeviceType
  5459. )
  5460. /*++
  5461. Routine Description:
  5462. look up compatible ID string
  5463. Arguments:
  5464. DeviceType - SCSI device type
  5465. Return Value:
  5466. compatible ID string
  5467. --*/
  5468. {
  5469. if (DeviceType < (sizeof (TffsDeviceType_tffsport) / sizeof (TFFS_DEVICE_TYPE))) {
  5470. return TffsDeviceType_tffsport[DeviceType].CompatibleIdString;
  5471. } else {
  5472. return NULL;
  5473. }
  5474. }
  5475. PCSTR
  5476. TrueffsGetCompatibleIdStringFDO (
  5477. IN ULONG DeviceType
  5478. )
  5479. /*++
  5480. Routine Description:
  5481. look up compatible ID string
  5482. Arguments:
  5483. DeviceType - SCSI device type
  5484. Return Value:
  5485. compatible ID string
  5486. --*/
  5487. {
  5488. if (DeviceType < (sizeof (TffsDeviceType_tffsport) / sizeof (TFFS_DEVICE_TYPE))) {
  5489. return TffsDeviceTypeFDO_tffsport[DeviceType].CompatibleIdString;
  5490. } else {
  5491. return NULL;
  5492. }
  5493. }
  5494. PCSTR
  5495. TrueffsGetPeripheralIdString (
  5496. IN ULONG DeviceType
  5497. )
  5498. /*++
  5499. Routine Description:
  5500. look up peripheral ID string
  5501. Arguments:
  5502. DeviceType - SCSI device type
  5503. Return Value:
  5504. Peripheral ID string
  5505. --*/
  5506. {
  5507. if (DeviceType < (sizeof (TffsDeviceType_tffsport) / sizeof (TFFS_DEVICE_TYPE))) {
  5508. return TffsDeviceType_tffsport[DeviceType].PeripheralIdString;
  5509. } else {
  5510. return NULL;
  5511. }
  5512. }
  5513. PCSTR
  5514. TrueffsGetPeripheralIdStringFDO (
  5515. IN ULONG DeviceType
  5516. )
  5517. /*++
  5518. Routine Description:
  5519. look up peripheral ID string
  5520. Arguments:
  5521. DeviceType - SCSI device type
  5522. Return Value:
  5523. Peripheral ID string
  5524. --*/
  5525. {
  5526. if (DeviceType < (sizeof (TffsDeviceType_tffsport) / sizeof (TFFS_DEVICE_TYPE))) {
  5527. return TffsDeviceTypeFDO_tffsport[DeviceType].PeripheralIdString;
  5528. } else {
  5529. return NULL;
  5530. }
  5531. }
  5532. NTSTATUS
  5533. TrueffsQueryDeviceRelations (
  5534. IN PDEVICE_OBJECT DeviceObject,
  5535. IN OUT PIRP Irp,
  5536. BOOLEAN Fdo
  5537. )
  5538. {
  5539. PIO_STACK_LOCATION thisIrpSp = IoGetCurrentIrpStackLocation(Irp);
  5540. PDEVICE_RELATIONS deviceRelations;
  5541. NTSTATUS status = STATUS_SUCCESS;
  5542. if (Fdo)
  5543. {
  5544. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  5545. switch (thisIrpSp->Parameters.QueryDeviceRelations.Type)
  5546. {
  5547. case BusRelations:
  5548. TffsDebugPrint ((TFFS_DEB_INFO,"Trueffs: QueryDeviceRelations: bus relations\n"));
  5549. if (deviceExtension->ChildPdo != NULL)
  5550. {
  5551. deviceRelations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS), TFFSPORT_POOL_TAG);
  5552. if (deviceRelations)
  5553. {
  5554. ObReferenceObject(deviceExtension->ChildPdo);
  5555. deviceRelations->Objects[0] = deviceExtension->ChildPdo;
  5556. deviceRelations->Count = 1;
  5557. Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
  5558. }
  5559. else
  5560. {
  5561. TffsDebugPrint ((TFFS_DEB_ERROR,"Trueffs: QueryDeviceRelations: Unable to allocate DeviceRelations structures\n"));
  5562. status = STATUS_INSUFFICIENT_RESOURCES;
  5563. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  5564. }
  5565. }
  5566. Irp->IoStatus.Status = status;
  5567. if (NT_SUCCESS(status))
  5568. {
  5569. //
  5570. // Send the request down in case a lower driver wants to append to the device relations
  5571. //
  5572. IoCopyCurrentIrpStackLocationToNext(Irp);
  5573. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  5574. }
  5575. else
  5576. {
  5577. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  5578. }
  5579. break;
  5580. default:
  5581. //
  5582. // Forward this request down, in case a lower driver understands it
  5583. //
  5584. IoSkipCurrentIrpStackLocation(Irp);
  5585. status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
  5586. break;
  5587. }
  5588. }
  5589. else
  5590. {
  5591. switch (thisIrpSp->Parameters.QueryDeviceRelations.Type)
  5592. {
  5593. case TargetDeviceRelation:
  5594. TffsDebugPrint ((TFFS_DEB_INFO,"Trueffs: QueryDeviceRelations: target relations\n"));
  5595. deviceRelations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS), TFFSPORT_POOL_TAG);
  5596. if (deviceRelations)
  5597. {
  5598. ObReferenceObject(DeviceObject);
  5599. deviceRelations->Objects[0] = DeviceObject;
  5600. deviceRelations->Count = 1;
  5601. Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
  5602. }
  5603. else
  5604. {
  5605. TffsDebugPrint ((TFFS_DEB_ERROR,"Trueffs: QueryDeviceRelations: Unable to allocate DeviceRelations structures\n"));
  5606. status = STATUS_INSUFFICIENT_RESOURCES;
  5607. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  5608. }
  5609. Irp->IoStatus.Status = status;
  5610. break;
  5611. default:
  5612. //
  5613. // Complete this request without altering its status
  5614. //
  5615. status = Irp->IoStatus.Status;
  5616. break;
  5617. }
  5618. Irp->IoStatus.Status = status;
  5619. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  5620. }
  5621. return status;
  5622. }
  5623. BOOLEAN
  5624. TrueffsOkToDetectLegacy (
  5625. IN PDRIVER_OBJECT DriverObject
  5626. )
  5627. {
  5628. NTSTATUS status;
  5629. ULONG legacyDetection;
  5630. status = TrueffsGetParameterFromServiceSubKey (
  5631. DriverObject,
  5632. LEGACY_DETECTION,
  5633. REG_DWORD,
  5634. TRUE,
  5635. (PVOID) &legacyDetection,
  5636. 0
  5637. );
  5638. if (!NT_SUCCESS(status) || legacyDetection) {
  5639. return TRUE;
  5640. }
  5641. else {
  5642. return FALSE;
  5643. }
  5644. }
  5645. NTSTATUS
  5646. TrueffsGetParameterFromServiceSubKey (
  5647. IN PDRIVER_OBJECT DriverObject,
  5648. IN PWSTR ParameterName,
  5649. IN ULONG ParameterType,
  5650. IN BOOLEAN Read,
  5651. OUT PVOID *ParameterValue,
  5652. IN ULONG ParameterValueWriteSize
  5653. )
  5654. {
  5655. NTSTATUS status;
  5656. HANDLE deviceParameterHandle;
  5657. RTL_QUERY_REGISTRY_TABLE queryTable[2] = { 0 };
  5658. ULONG defaultParameterValue;
  5659. CCHAR deviceBuffer[50];
  5660. ANSI_STRING ansiString;
  5661. UNICODE_STRING subKeyPath;
  5662. HANDLE subServiceKey;
  5663. UNICODE_STRING unicodeParameterName;
  5664. RtlZeroMemory(ParameterValue, ParameterValueWriteSize);
  5665. sprintf (deviceBuffer, DRIVER_PARAMETER_SUBKEY);
  5666. RtlInitAnsiString(&ansiString, deviceBuffer);
  5667. status = RtlAnsiStringToUnicodeString(&subKeyPath, &ansiString, TRUE);
  5668. if (NT_SUCCESS(status)) {
  5669. subServiceKey = TrueffsOpenServiceSubKey (
  5670. DriverObject,
  5671. &subKeyPath
  5672. );
  5673. RtlFreeUnicodeString (&subKeyPath);
  5674. if (subServiceKey) {
  5675. if (Read) {
  5676. queryTable->QueryRoutine = TrueffsRegQueryRoutine;
  5677. queryTable->Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
  5678. queryTable->Name = ParameterName;
  5679. queryTable->EntryContext = ParameterValue;
  5680. queryTable->DefaultType = 0;
  5681. queryTable->DefaultData = NULL;
  5682. queryTable->DefaultLength = 0;
  5683. status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
  5684. (PWSTR) subServiceKey,
  5685. queryTable,
  5686. ULongToPtr( ParameterType ),
  5687. NULL);
  5688. } else {
  5689. RtlInitUnicodeString (&unicodeParameterName, ParameterName);
  5690. status = ZwSetValueKey(
  5691. subServiceKey,
  5692. &unicodeParameterName,
  5693. 0,
  5694. ParameterType,
  5695. ParameterValue,
  5696. ParameterValueWriteSize
  5697. );
  5698. }
  5699. // close what we open
  5700. TrueffsCloseServiceSubKey (
  5701. subServiceKey
  5702. );
  5703. }
  5704. }
  5705. return status;
  5706. }
  5707. NTSTATUS
  5708. TrueffsRegQueryRoutine (
  5709. IN PWSTR ValueName,
  5710. IN ULONG ValueType,
  5711. IN PVOID ValueData,
  5712. IN ULONG ValueLength,
  5713. IN PVOID Context,
  5714. IN PVOID EntryContext
  5715. )
  5716. {
  5717. PVOID *parameterValue = EntryContext;
  5718. ULONG parameterType = PtrToUlong(Context);
  5719. if (ValueType == parameterType) {
  5720. if (ValueType == REG_MULTI_SZ) {
  5721. *parameterValue = ExAllocatePoolWithTag(PagedPool, ValueLength, TFFSPORT_POOL_TAG);
  5722. if (*parameterValue) {
  5723. RtlMoveMemory(*parameterValue, ValueData, ValueLength);
  5724. return STATUS_SUCCESS;
  5725. }
  5726. } else if (ValueType == REG_DWORD) {
  5727. PULONG ulongValue;
  5728. ulongValue = (PULONG) parameterValue;
  5729. *ulongValue = *((PULONG) ValueData);
  5730. return STATUS_SUCCESS;
  5731. }
  5732. }
  5733. return STATUS_UNSUCCESSFUL;
  5734. }
  5735. HANDLE
  5736. TrueffsOpenServiceSubKey (
  5737. IN PDRIVER_OBJECT DriverObject,
  5738. IN PUNICODE_STRING SubKeyPath
  5739. )
  5740. {
  5741. PTRUEFFSDRIVER_EXTENSION trueffsDriverExtension;
  5742. OBJECT_ATTRIBUTES objectAttributes;
  5743. HANDLE serviceKey;
  5744. HANDLE subServiceKey;
  5745. NTSTATUS status;
  5746. ULONG disposition;
  5747. trueffsDriverExtension = IoGetDriverObjectExtension(
  5748. DriverObject,
  5749. DRIVER_OBJECT_EXTENSION_ID
  5750. );
  5751. if (!trueffsDriverExtension) {
  5752. return NULL;
  5753. }
  5754. InitializeObjectAttributes(&objectAttributes,
  5755. &trueffsDriverExtension->RegistryPath,
  5756. OBJ_CASE_INSENSITIVE,
  5757. NULL,
  5758. (PSECURITY_DESCRIPTOR) NULL);
  5759. status = ZwOpenKey(&serviceKey,
  5760. KEY_ALL_ACCESS,
  5761. &objectAttributes);
  5762. if (!NT_SUCCESS(status)) {
  5763. return NULL;
  5764. }
  5765. InitializeObjectAttributes(&objectAttributes,
  5766. SubKeyPath,
  5767. OBJ_CASE_INSENSITIVE,
  5768. serviceKey,
  5769. (PSECURITY_DESCRIPTOR) NULL);
  5770. status = ZwCreateKey(&subServiceKey,
  5771. KEY_READ | KEY_WRITE,
  5772. &objectAttributes,
  5773. 0,
  5774. (PUNICODE_STRING) NULL,
  5775. REG_OPTION_NON_VOLATILE,
  5776. &disposition);
  5777. ZwClose(serviceKey);
  5778. if (NT_SUCCESS(status)) {
  5779. return subServiceKey;
  5780. } else {
  5781. return NULL;
  5782. }
  5783. }
  5784. VOID
  5785. TrueffsCloseServiceSubKey (
  5786. IN HANDLE SubServiceKey
  5787. )
  5788. {
  5789. ZwClose(SubServiceKey);
  5790. }
  5791. PPDO_EXTENSION
  5792. AllocatePdo(
  5793. IN PDEVICE_EXTENSION FdoExtension
  5794. )
  5795. /*++
  5796. Routine Description:
  5797. Create physical device object
  5798. Arguments:
  5799. DeviceExtension
  5800. Return Value:
  5801. Physical device object
  5802. --*/
  5803. {
  5804. PDEVICE_OBJECT physicalDeviceObject = NULL;
  5805. PPDO_EXTENSION pdoExtension;
  5806. NTSTATUS status;
  5807. STRING deviceName;
  5808. CCHAR deviceNameBuffer[64];
  5809. UNICODE_STRING unicodeDeviceNameString;
  5810. sprintf(deviceNameBuffer, "\\Device\\TrueffsDevice%d",
  5811. FdoExtension->TrueffsDeviceNumber
  5812. );
  5813. RtlInitString(&deviceName, deviceNameBuffer);
  5814. status = RtlAnsiStringToUnicodeString(&unicodeDeviceNameString,
  5815. &deviceName,
  5816. TRUE);
  5817. if (!NT_SUCCESS (status)) {
  5818. return NULL;
  5819. }
  5820. status = IoCreateDevice(
  5821. FdoExtension->DriverObject, // our driver object
  5822. sizeof(PDO_EXTENSION), // size of our extension
  5823. &unicodeDeviceNameString, // our name
  5824. FILE_DEVICE_DISK, // device type
  5825. FILE_DEVICE_SECURE_OPEN, // device characteristics
  5826. FALSE, // not exclusive
  5827. &physicalDeviceObject // store new device object here
  5828. );
  5829. if (NT_SUCCESS(status)) {
  5830. pdoExtension = physicalDeviceObject->DeviceExtension;
  5831. RtlZeroMemory (pdoExtension, sizeof(PDO_EXTENSION));
  5832. pdoExtension->DeviceObject = physicalDeviceObject;
  5833. pdoExtension->DriverObject = FdoExtension->DriverObject;
  5834. pdoExtension->Pext = FdoExtension;
  5835. pdoExtension->SystemPowerState = PowerSystemWorking;
  5836. pdoExtension->DevicePowerState = PowerDeviceD0;
  5837. }
  5838. RtlFreeUnicodeString (&unicodeDeviceNameString);
  5839. if (physicalDeviceObject == NULL) {
  5840. return NULL;
  5841. }
  5842. FdoExtension->ChildPdo = physicalDeviceObject;
  5843. physicalDeviceObject->Flags |= DO_DIRECT_IO;
  5844. physicalDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
  5845. physicalDeviceObject->Flags &=~DO_DEVICE_INITIALIZING;
  5846. return pdoExtension;
  5847. }
  5848. NTSTATUS
  5849. TrueffsDeviceQueryCapabilities(IN PDEVICE_EXTENSION deviceExtension,
  5850. IN PDEVICE_CAPABILITIES Capabilities
  5851. )
  5852. {
  5853. Capabilities->UniqueID = FALSE;
  5854. Capabilities->LockSupported = FALSE;
  5855. Capabilities->EjectSupported = FALSE;
  5856. Capabilities->DockDevice = FALSE;
  5857. Capabilities->SilentInstall = FALSE;
  5858. Capabilities->RawDeviceOK = FALSE;
  5859. Capabilities->Removable = deviceExtension->removableMedia;
  5860. Capabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
  5861. Capabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
  5862. Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
  5863. Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
  5864. Capabilities->SystemWake = PowerSystemUnspecified;
  5865. Capabilities->DeviceWake = PowerDeviceUnspecified;
  5866. Capabilities->D1Latency = 0;
  5867. Capabilities->D2Latency = 0;
  5868. Capabilities->D3Latency = 10; // 1ms
  5869. return STATUS_SUCCESS;
  5870. }
  5871. typedef enum {
  5872. FlashDiskInfo = 0
  5873. } WMI_DATA_BLOCK_TYPE;
  5874. #define MOFRESOURCENAME L"MofResourceName"
  5875. #define NUMBER_OF_WMI_GUID 1
  5876. WMIGUIDREGINFO TrueffsWmiGuidList[NUMBER_OF_WMI_GUID];
  5877. VOID
  5878. TrueffsWmiInit (VOID)
  5879. {
  5880. TrueffsWmiGuidList[FlashDiskInfo].Guid = &WmiTffsportAddressGuid;
  5881. TrueffsWmiGuidList[FlashDiskInfo].InstanceCount = 1;
  5882. TrueffsWmiGuidList[FlashDiskInfo].Flags = 0;
  5883. return;
  5884. }
  5885. NTSTATUS
  5886. TrueffsWmiRegister(
  5887. PDEVICE_EXTENSION_HEADER DevExtension
  5888. )
  5889. {
  5890. NTSTATUS status;
  5891. DevExtension->WmiLibInfo.GuidCount = NUMBER_OF_WMI_GUID;
  5892. DevExtension->WmiLibInfo.GuidList = TrueffsWmiGuidList;
  5893. DevExtension->WmiLibInfo.QueryWmiDataBlock = TrueffsQueryWmiDataBlock;
  5894. DevExtension->WmiLibInfo.QueryWmiRegInfo = TrueffsQueryWmiRegInfo;
  5895. DevExtension->WmiLibInfo.SetWmiDataBlock = TrueffsSetWmiDataBlock;
  5896. DevExtension->WmiLibInfo.SetWmiDataItem = TrueffsSetWmiDataItem;
  5897. DevExtension->WmiLibInfo.ExecuteWmiMethod = NULL;
  5898. DevExtension->WmiLibInfo.WmiFunctionControl = NULL;
  5899. status = IoWMIRegistrationControl(DevExtension->DeviceObject,WMIREG_ACTION_REGISTER);
  5900. if (!NT_SUCCESS(status)) {
  5901. TffsDebugPrint((TFFS_DEB_ERROR,
  5902. "TrueffsWmiRegister: IoWMIRegistrationControl(%x, WMI_ACTION_REGISTER) failed\n",
  5903. DevExtension->DeviceObject));
  5904. }
  5905. return status;
  5906. }
  5907. NTSTATUS
  5908. TrueffsWmiDeregister(
  5909. PDEVICE_EXTENSION_HEADER DevExtension
  5910. )
  5911. {
  5912. NTSTATUS status;
  5913. status = IoWMIRegistrationControl(DevExtension->DeviceObject,WMIREG_ACTION_DEREGISTER);
  5914. if (!NT_SUCCESS(status)) {
  5915. TffsDebugPrint((TFFS_DEB_ERROR,
  5916. "TrueffsWmiRegister: IoWMIRegistrationControl(%x, WMIREG_ACTION_DEREGISTER) failed\n",
  5917. DevExtension->DeviceObject));
  5918. }
  5919. return status;
  5920. }
  5921. NTSTATUS
  5922. TrueffsWmiSystemControl(
  5923. IN PDEVICE_OBJECT DeviceObject,
  5924. IN PIRP Irp
  5925. )
  5926. /*++
  5927. Routine Description
  5928. We have just received a System Control IRP.
  5929. Assume that this is a WMI IRP and call into the WMI system library and let
  5930. it handle this IRP for us.
  5931. --*/
  5932. {
  5933. PPDO_EXTENSION pdoExtension;
  5934. SYSCTL_IRP_DISPOSITION disposition;
  5935. NTSTATUS status;
  5936. pdoExtension = DeviceObject->DeviceExtension;
  5937. if (pdoExtension) {
  5938. status = WmiSystemControl(&pdoExtension->WmiLibInfo,
  5939. DeviceObject,
  5940. Irp,
  5941. &disposition);
  5942. switch(disposition)
  5943. {
  5944. case IrpProcessed:
  5945. {
  5946. // This irp has been processed and may be completed or pending.
  5947. break;
  5948. }
  5949. case IrpNotCompleted:
  5950. {
  5951. // This irp has not been completed, but has been fully
  5952. // processed. We will complete it now
  5953. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  5954. break;
  5955. }
  5956. case IrpForward:
  5957. case IrpNotWmi:
  5958. default:
  5959. {
  5960. Irp->IoStatus.Status = status = STATUS_NOT_SUPPORTED;
  5961. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  5962. break;
  5963. }
  5964. }
  5965. } else {
  5966. Irp->IoStatus.Status = status = STATUS_UNSUCCESSFUL;
  5967. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  5968. }
  5969. return status;
  5970. }
  5971. NTSTATUS
  5972. TrueffsQueryWmiDataBlock(
  5973. IN PDEVICE_OBJECT DeviceObject,
  5974. IN PIRP Irp,
  5975. IN ULONG GuidIndex,
  5976. IN ULONG InstanceIndex,
  5977. IN ULONG InstanceCount,
  5978. IN OUT PULONG InstanceLengthArray,
  5979. IN ULONG OutBufferSize,
  5980. OUT PUCHAR Buffer
  5981. )
  5982. /*++
  5983. Routine Description:
  5984. This routine is a callback into the driver to query for the contents of
  5985. a data block. When the driver has finished filling the data block it
  5986. must call ClassWmiCompleteRequest to complete the irp. The driver can
  5987. return STATUS_PENDING if the irp cannot be completed immediately.
  5988. Arguments:
  5989. DeviceObject is the device whose data block is being queried
  5990. Irp is the Irp that makes this request
  5991. GuidIndex is the index into the list of guids provided when the
  5992. device registered
  5993. InstanceIndex is the index that denotes which instance of the data block
  5994. is being queried.
  5995. InstanceCount is the number of instances expected to be returned for
  5996. the data block.
  5997. InstanceLengthArray is a pointer to an array of ULONG that returns the
  5998. lengths of each instance of the data block. If this is NULL then
  5999. there was not enough space in the output buffer to fufill the request
  6000. so the irp should be completed with the buffer needed.
  6001. BufferAvail on has the maximum size available to write the data
  6002. block.
  6003. Buffer on return is filled with the returned data block
  6004. Return Value:
  6005. status
  6006. --*/
  6007. {
  6008. PPDO_EXTENSION pdoExtension;
  6009. NTSTATUS status;
  6010. ULONG numBytesReturned = sizeof(WMI_FLASH_DISK_INFO);
  6011. pdoExtension = DeviceObject->DeviceExtension;
  6012. if (!pdoExtension) {
  6013. Irp->IoStatus.Status = status = STATUS_UNSUCCESSFUL;
  6014. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  6015. return status;
  6016. }
  6017. switch (GuidIndex) {
  6018. case FlashDiskInfo: {
  6019. PWMI_FLASH_DISK_INFO flashDiskInfo;
  6020. if (OutBufferSize < sizeof(WMI_FLASH_DISK_INFO)) {
  6021. status = STATUS_BUFFER_TOO_SMALL;
  6022. } else {
  6023. flashDiskInfo = (PWMI_FLASH_DISK_INFO) Buffer;
  6024. flashDiskInfo->Number = pdoExtension->Pext->TrueffsDeviceNumber;
  6025. flashDiskInfo->Address = (ULONG) pdoExtension->Pext->pcmciaParams.physWindow;
  6026. flashDiskInfo->Size = pdoExtension->Pext->pcmciaParams.windowSize;
  6027. *InstanceLengthArray = sizeof(WMI_FLASH_DISK_INFO);
  6028. status = STATUS_SUCCESS;
  6029. }
  6030. break;
  6031. }
  6032. default:
  6033. status = STATUS_WMI_GUID_NOT_FOUND;
  6034. break;
  6035. }
  6036. status = WmiCompleteRequest( DeviceObject,
  6037. Irp,
  6038. status,
  6039. numBytesReturned,
  6040. IO_NO_INCREMENT
  6041. );
  6042. return status;
  6043. }
  6044. NTSTATUS
  6045. TrueffsQueryWmiRegInfo(
  6046. IN PDEVICE_OBJECT DeviceObject,
  6047. OUT PULONG RegFlags,
  6048. OUT PUNICODE_STRING InstanceName,
  6049. OUT PUNICODE_STRING *RegistryPath,
  6050. OUT PUNICODE_STRING MofResourceName,
  6051. OUT PDEVICE_OBJECT *Pdo
  6052. )
  6053. /*++
  6054. Routine Description:
  6055. This routine is a callback into the driver to retrieve the list of
  6056. guids or data blocks that the driver wants to register with WMI. This
  6057. routine may not pend or block. Driver should NOT call
  6058. ClassWmiCompleteRequest.
  6059. Arguments:
  6060. DeviceObject is the device whose data block is being queried
  6061. *RegFlags returns with a set of flags that describe the guids being
  6062. registered for this device. If the device wants enable and disable
  6063. collection callbacks before receiving queries for the registered
  6064. guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
  6065. returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
  6066. the instance name is determined from the PDO associated with the
  6067. device object. Note that the PDO must have an associated devnode. If
  6068. WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
  6069. name for the device.
  6070. InstanceName returns with the instance name for the guids if
  6071. WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
  6072. caller will call ExFreePool with the buffer returned.
  6073. *RegistryPath returns with the registry path of the driver
  6074. *MofResourceName returns with the name of the MOF resource attached to
  6075. the binary file. If the driver does not have a mof resource attached
  6076. then this can be returned as NULL.
  6077. *Pdo returns with the device object for the PDO associated with this
  6078. device if the WMIREG_FLAG_INSTANCE_PDO flag is retured in
  6079. *RegFlags.
  6080. Return Value:
  6081. status
  6082. --*/
  6083. {
  6084. PTRUEFFSDRIVER_EXTENSION trueffsDriverExtension;
  6085. PPDO_EXTENSION pdoExtension;
  6086. NTSTATUS status;
  6087. pdoExtension = DeviceObject->DeviceExtension;
  6088. if (!pdoExtension) {
  6089. status = STATUS_UNSUCCESSFUL;
  6090. } else {
  6091. trueffsDriverExtension = IoGetDriverObjectExtension(
  6092. pdoExtension->DriverObject,
  6093. DRIVER_OBJECT_EXTENSION_ID
  6094. );
  6095. if (!trueffsDriverExtension) {
  6096. status = STATUS_UNSUCCESSFUL;
  6097. } else {
  6098. *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
  6099. *RegistryPath = &trueffsDriverExtension->RegistryPath;
  6100. *Pdo = pdoExtension->DeviceObject;
  6101. RtlInitUnicodeString(MofResourceName, MOFRESOURCENAME);
  6102. status = STATUS_SUCCESS;
  6103. }
  6104. }
  6105. return status;
  6106. }
  6107. NTSTATUS
  6108. TrueffsSetWmiDataBlock(
  6109. IN PDEVICE_OBJECT DeviceObject,
  6110. IN PIRP Irp,
  6111. IN ULONG GuidIndex,
  6112. IN ULONG InstanceIndex,
  6113. IN ULONG BufferSize,
  6114. IN PUCHAR Buffer
  6115. )
  6116. /*++
  6117. Routine Description:
  6118. This routine is a callback into the driver to set the contents of
  6119. a data block. When the driver has finished filling the data block it
  6120. must call ClassWmiCompleteRequest to complete the irp. The driver can
  6121. return STATUS_PENDING if the irp cannot be completed immediately.
  6122. Arguments:
  6123. DeviceObject is the device whose data block is being queried
  6124. Irp is the Irp that makes this request
  6125. GuidIndex is the index into the list of guids provided when the
  6126. device registered
  6127. InstanceIndex is the index that denotes which instance of the data block
  6128. is being set.
  6129. BufferSize has the size of the data block passed
  6130. Buffer has the new values for the data block
  6131. Return Value:
  6132. status
  6133. --*/
  6134. {
  6135. PPDO_EXTENSION pdoExtension;
  6136. NTSTATUS status;
  6137. pdoExtension = DeviceObject->DeviceExtension;
  6138. if (!pdoExtension) {
  6139. status = STATUS_UNSUCCESSFUL;
  6140. } else {
  6141. switch (GuidIndex) {
  6142. case FlashDiskInfo: {
  6143. status = /*STATUS_WMI_READ_ONLY;*/ STATUS_INVALID_DEVICE_REQUEST;
  6144. break;
  6145. }
  6146. default:
  6147. status = STATUS_WMI_GUID_NOT_FOUND;
  6148. }
  6149. status = WmiCompleteRequest( DeviceObject,
  6150. Irp,
  6151. status,
  6152. 0,
  6153. IO_NO_INCREMENT
  6154. );
  6155. }
  6156. return status;
  6157. }
  6158. NTSTATUS
  6159. TrueffsSetWmiDataItem(
  6160. IN PDEVICE_OBJECT DeviceObject,
  6161. IN PIRP Irp,
  6162. IN ULONG GuidIndex,
  6163. IN ULONG InstanceIndex,
  6164. IN ULONG DataItemId,
  6165. IN ULONG BufferSize,
  6166. IN PUCHAR Buffer
  6167. )
  6168. /*++
  6169. Routine Description:
  6170. This routine is a callback into the driver to set for the contents of
  6171. a data block. When the driver has finished filling the data block it
  6172. must call ClassWmiCompleteRequest to complete the irp. The driver can
  6173. return STATUS_PENDING if the irp cannot be completed immediately.
  6174. Arguments:
  6175. DeviceObject is the device whose data block is being queried
  6176. Irp is the Irp that makes this request
  6177. GuidIndex is the index into the list of guids provided when the
  6178. device registered
  6179. InstanceIndex is the index that denotes which instance of the data block
  6180. is being set.
  6181. DataItemId has the id of the data item being set
  6182. BufferSize has the size of the data item passed
  6183. Buffer has the new values for the data item
  6184. Return Value:
  6185. status
  6186. --*/
  6187. {
  6188. PPDO_EXTENSION pdoExtension;
  6189. NTSTATUS status;
  6190. pdoExtension = DeviceObject->DeviceExtension;
  6191. if (!pdoExtension) {
  6192. status = STATUS_UNSUCCESSFUL;
  6193. } else {
  6194. switch(GuidIndex) {
  6195. case FlashDiskInfo: {
  6196. status = /*STATUS_WMI_READ_ONLY;*/ STATUS_INVALID_DEVICE_REQUEST;
  6197. break;
  6198. }
  6199. default:
  6200. status = STATUS_WMI_GUID_NOT_FOUND;
  6201. break;
  6202. }
  6203. status = WmiCompleteRequest( DeviceObject,
  6204. Irp,
  6205. status,
  6206. 0,
  6207. IO_NO_INCREMENT
  6208. );
  6209. }
  6210. return status;
  6211. }
  6212. BOOLEAN
  6213. DebugLogEvent(IN PDRIVER_OBJECT DriverObject, IN ULONG Value)
  6214. {
  6215. NTSTATUS status;
  6216. ULONG DebugValue = Value;
  6217. DebugValue++;
  6218. // write registry debug value
  6219. status = TrueffsGetParameterFromServiceSubKey(DriverObject,
  6220. L"DebugValue",
  6221. REG_DWORD,
  6222. FALSE,
  6223. (PVOID) &DebugValue,
  6224. sizeof(DebugValue));
  6225. return STATUS_SUCCESS;
  6226. }
  6227. #if DBG
  6228. ULONG TffsDebugPrintLevel = TFFS_DEB_ERROR;
  6229. VOID
  6230. TrueffsDebugPrint(ULONG DebugPrintLevel, PCHAR DebugMessage, ...)
  6231. {
  6232. va_list ap;
  6233. va_start(ap, DebugMessage);
  6234. if (DebugPrintLevel & TffsDebugPrintLevel)
  6235. {
  6236. DbgPrint(DebugMessage, ap);
  6237. }
  6238. va_end(ap);
  6239. }
  6240. VOID
  6241. PRINTF(PCHAR DebugMessage, ...)
  6242. {
  6243. va_list ap;
  6244. va_start(ap, DebugMessage);
  6245. TrueffsDebugPrint(TFFS_DEB_INFO, DebugMessage, ap);
  6246. va_end(ap);
  6247. }
  6248. #else
  6249. VOID
  6250. PRINTF(PCHAR DebugMessage, ...)
  6251. {
  6252. }
  6253. #endif