1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
4 ////////////////////////////////////////////////////////////////////
5 /*************************************************************************
9 * Module: UDF File System Driver (Kernel mode execution only)
12 * This file contains the initialization code for the kernel mode
13 * UDF FSD module. The DriverEntry() routine is called by the I/O
14 * sub-system to initialize the FSD.
16 *************************************************************************/
20 // define the file specific bug-check id
21 #define UDF_BUG_CHECK_ID UDF_FILE_INIT
23 // global variables are declared here
24 UDFData UDFGlobalData
;
26 #ifdef EVALUATION_TIME_LIMIT
28 ULONG PresentDateMask
= 0;
29 BOOLEAN TrialEndOnStart
= FALSE
;
31 #define UDF_MD5Init UDF_MD5Init2
32 #define UDF_MD5Update UDF_MD5Update2
33 #define UDF_MD5Pad UDF_MD5Pad2
34 #define UDF_MD5Final UDF_MD5Final2
35 #define UDF_MD5End UDF_MD5End2
36 #define UDF_MD5Transform UDF_MD5Transform2
37 #define UDF_Encode UDF_Encode2
38 #define UDF_Decode UDF_Decode2
39 #define PADDING PADDING2
41 #define ROTATE_LEFT ROTATE_LEFT2
47 #define UDF_MD5Transform_dwords UDF_MD5Transform_dwords2
48 #define UDF_MD5Transform_idx UDF_MD5Transform_idx2
49 #define UDF_MD5Transform_Sxx UDF_MD5Transform_Sxx2
50 #define UDF_MD5Rotate UDF_MD5Rotate2
52 #include "..\Include\md5.h"
53 #include "..\Include\md5c.c"
55 #define UDF_FibonachiNum UDF_FibonachiNum2
57 #define UDF_build_long_key UDF_build_long_key2
58 #define UDF_build_hash_by_key UDF_build_hash_by_key2
60 #include "..\Include\key_lib.h"
61 #include "..\Include\key_lib.cpp"
63 extern ULONG UDFNumberOfKeys
;
64 extern PCHAR pUDFLongKey
;
65 extern PUDF_KEY_LIST pUDFKeyList
;
66 extern PUCHAR pRegKeyName0
;
68 #include "..\Include\protect.h"
69 #define INCLUDE_XOR_DECL_ONLY
70 #include "..\Include\protect.h"
71 #undef INCLUDE_XOR_DECL_ONLY
73 #endif //EVALUATION_TIME_LIMIT
77 struct UDF_MEDIA_CLASS_NAMES UDFMediaClassName
[] = {
78 {MediaUnknown
, REG_DEFAULT_UNKNOWN
},
79 {MediaHdd
, REG_DEFAULT_HDD
},
80 {MediaCdr
, REG_DEFAULT_CDR
},
81 {MediaCdrw
, REG_DEFAULT_CDRW
},
82 {MediaCdrom
, REG_DEFAULT_CDROM
},
83 {MediaZip
, REG_DEFAULT_ZIP
},
84 {MediaFloppy
, REG_DEFAULT_FLOPPY
},
85 {MediaDvdr
, REG_DEFAULT_DVDR
},
86 {MediaDvdrw
, REG_DEFAULT_DVDRW
}
89 ULONG MajorVersion = 0;
90 ULONG MinorVersion = 0;
91 ULONG BuildNumber = 0;
93 ULONG FsRegistered
= FALSE
;
95 WORK_QUEUE_ITEM RemountWorkQueueItem
;
97 //ptrFsRtlNotifyVolumeEvent FsRtlNotifyVolumeEvent = NULL;
99 HANDLE FsNotification_ThreadId
= (HANDLE
)(-1);
102 UDFCreateFsDeviceObject(
104 PDRIVER_OBJECT DriverObject
,
105 DEVICE_TYPE DeviceType
,
106 PDEVICE_OBJECT
*DeviceObject
);
110 PUNICODE_STRING unicodeCdRomDeviceName
);
116 /*************************************************************************
118 * Function: DriverEntry()
121 * This routine is the standard entry point for all kernel mode drivers.
122 * The routine is invoked at IRQL PASSIVE_LEVEL in the context of a
123 * system worker thread.
124 * All FSD specific data structures etc. are initialized here.
126 * Expected Interrupt Level (for execution) :
130 * Return Value: STATUS_SUCCESS/Error (will cause driver to be unloaded).
132 *************************************************************************/
136 PDRIVER_OBJECT DriverObject
, // created by the I/O sub-system
137 PUNICODE_STRING RegistryPath
// path to the registry key
140 NTSTATUS RC
= STATUS_SUCCESS
;
141 UNICODE_STRING DriverDeviceName
;
142 UNICODE_STRING unicodeDeviceName
;
143 // BOOLEAN RegisteredShutdown = FALSE;
144 BOOLEAN InternalMMInitialized
= FALSE
;
145 // BOOLEAN DLDetectInitialized = FALSE;
146 // ULONG CdRomNumber;
147 // CCHAR deviceNameBuffer[MAXIMUM_FILENAME_LENGTH];
148 // ANSI_STRING deviceName;
149 // UNICODE_STRING unicodeCdRomDeviceName;
150 PUDFFS_DEV_EXTENSION FSDevExt
;
152 #ifdef EVALUATION_TIME_LIMIT
154 WCHAR RegKeyName
[64];
155 CHAR LicenseKey
[16+1];
159 int checksum
[4] = {0,0,0,0};
162 #endif //EVALUATION_TIME_LIMIT
164 // KdPrint(("UDF: Entered " VER_STR_PRODUCT_NAME " UDF DriverEntry \n"));
165 // KdPrint((KD_PREFIX "Build " VER_STR_PRODUCT "\n"));
167 #ifdef EVALUATION_TIME_LIMIT
169 #endif //EVALUATION_TIME_LIMIT
174 #ifdef EVALUATION_TIME_LIMIT
176 #endif //EVALUATION_TIME_LIMIT
179 CrNtInit(DriverObject, RegistryPath);
181 //PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
182 KdPrint(("UDF: OS Version Major: %x, Minor: %x, Build number: %d\n",
183 MajorVersion, MinorVersion, BuildNumber));
186 KdPrint(("UDF Init: OS should be ReactOS\n"));
189 // initialize the global data structure
190 RtlZeroMemory(&UDFGlobalData
, sizeof(UDFGlobalData
));
192 // initialize some required fields
193 UDFGlobalData
.NodeIdentifier
.NodeType
= UDF_NODE_TYPE_GLOBAL_DATA
;
194 UDFGlobalData
.NodeIdentifier
.NodeSize
= sizeof(UDFGlobalData
);
196 #ifdef EVALUATION_TIME_LIMIT
198 KeQuerySystemTime((PLARGE_INTEGER
)&cTime
);
202 t
= cTime
.QuadPart
/ 100;
207 KdPrint((KD_PREFIX
"t2 = %x\n", t2
));
208 if(t2
-TIME_JAN_1_2003
> UDF_MAX_DATE
||
209 t2
-TIME_JAN_1_2003
< UDF_MIN_DATE
) {
210 KdPrint((KD_PREFIX
"Ssytem time is out of range: %x <= %x <= %x\n",
211 UDF_MIN_DATE
, (uint32
)t2
-TIME_JAN_1_2003
, UDF_MAX_DATE
));
212 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
216 if(UDFGetTrialEnd(&iVer
)) {
217 TrialEndOnStart
= TRUE
;
218 KdPrint((KD_PREFIX
"Eval time expired some time ago\n"));
219 UDFGlobalData
.UDFFlags
= (UDFGlobalData
.UDFFlags
& ~UDF_DATA_FLAGS_UNREGISTERED
) + UDF_DATA_FLAGS_UNREGISTERED
;
221 cTime
.QuadPart
/= (10*1000*1000);
222 cTime
.QuadPart
/= (60*60*24);
224 KdPrint((KD_PREFIX
"cTime = %x, jTime = %x\n", cTime
.LowPart
, TIME_JAN_1_2003
));
225 if(cTime
.QuadPart
< TIME_JAN_1_2003
) {
226 KdPrint((KD_PREFIX
"System time %x < TIME_JAN_1_2003\n", cTime
.LowPart
));
227 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
229 cTime
.LowPart
-= TIME_JAN_1_2003
;
230 KdPrint(("cTime = %x\n", cTime
.LowPart
));
232 if(!UDFGetInstallVersion((PULONG
)&iVer
) ||
233 !UDFGetInstallTime((PULONG
)&cTime
.HighPart
)) {
234 KdPrint((KD_PREFIX
"UDFGetInstallTime() or UDFGetInstallVersion() failed\n"));
235 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
237 KdPrint((KD_PREFIX
"cTime = %x, iTime = %x\n", cTime
.LowPart
, cTime
.HighPart
));
238 if(iVer
> UDF_CURRENT_BUILD
) {
239 KdPrint(("Init: Detected newer build (0)\n"));
240 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
242 if((ULONG
)cTime
.LowPart
< (ULONG
)cTime
.HighPart
) {
243 KdPrint(("Eval time expired: current (%x) < install (%x)\n",
244 cTime
.LowPart
, cTime
.HighPart
));
245 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
247 if((ULONG
)cTime
.LowPart
> (ULONG
)cTime
.HighPart
+ EVALUATION_TERM
) {
248 KdPrint(("Eval time expired above EVALUATION_TERM\n"));
249 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
251 if((cTime
.HighPart
>> 16) & 0x8000) {
252 KdPrint(("Eval time expired (negative install time)\n"));
253 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
256 if(UDFGlobalData
.UDFFlags
& UDF_DATA_FLAGS_UNREGISTERED
) {
262 KdPrint(("Init: unregistered (3). Write BIAKAs to Registry\n"));
263 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
266 d
= 1 ^ XOR_VAR(TrialEnd
, 0);
267 swprintf(s
, L
"0x%8.8x\0", d
);
268 GET_TRIAL_REG_KEY_NAME(RegPath
, 0);
269 GET_TRIAL_REG_VAL_NAME(RegKeyName
, 0);
270 type
= GET_XXX_REG_VAL_TYPE(TRIAL
, 0) ? REG_SZ
: REG_DWORD
;
271 pdata
= GET_XXX_REG_VAL_TYPE(TRIAL
, 0) ? (PVOID
)s
: (PVOID
)&d
;
272 sz
= GET_XXX_REG_VAL_TYPE(TRIAL
, 0) ? (10+1+1)*sizeof(WCHAR
) : sizeof(d
);
273 KdPrint(("%ws\n %ws\n", RegPath
, RegKeyName
));
274 RC
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
/*| RTL_REGISTRY_OPTIONAL*/,
277 KdPrint(("status %#x\n", RC
));
278 d
= 1 ^ XOR_VAR(TrialEnd
, 1);
279 swprintf(s
, L
"0x%8.8x\0", d
);
280 GET_TRIAL_REG_KEY_NAME(RegPath
, 1);
281 GET_TRIAL_REG_VAL_NAME(RegKeyName
, 1);
282 type
= GET_XXX_REG_VAL_TYPE(TRIAL
, 1) ? REG_SZ
: REG_DWORD
;
283 pdata
= GET_XXX_REG_VAL_TYPE(TRIAL
, 1) ? (PVOID
)s
: (PVOID
)&d
;
284 sz
= GET_XXX_REG_VAL_TYPE(TRIAL
, 1) ? (10+1+1)*sizeof(WCHAR
) : sizeof(d
);
285 KdPrint(("%ws\n %ws\n", RegPath
, RegKeyName
));
286 RC
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
/*| RTL_REGISTRY_OPTIONAL*/,
289 KdPrint(("status %#x\n", RC
));
291 if(!TrialEndOnStart
) {
292 d
= UDFGlobalData
.iTime
^ XOR_VAR(Date
, 0);
293 swprintf(s
, L
"0x%8.8x\0", d
);
294 GET_DATE_REG_KEY_NAME(RegPath
, 0);
295 GET_DATE_REG_VAL_NAME(RegKeyName
, 0);
296 type
= GET_XXX_REG_VAL_TYPE(DATE
, 0) ? REG_SZ
: REG_DWORD
;
297 pdata
= GET_XXX_REG_VAL_TYPE(DATE
, 0) ? (PVOID
)s
: (PVOID
)&d
;
298 sz
= GET_XXX_REG_VAL_TYPE(DATE
, 0) ? (10+1+1)*sizeof(WCHAR
) : sizeof(d
);
299 if(!(PresentDateMask
& (1 << 0))) {
300 KdPrint(("%ws\n %ws\n", RegPath
, RegKeyName
));
301 RC
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
/*| RTL_REGISTRY_OPTIONAL*/,
304 KdPrint(("status %#x\n", RC
));
306 d
= UDFGlobalData
.iTime
^ XOR_VAR(Date
, 1);
307 swprintf(s
, L
"0x%8.8x\0", d
);
308 GET_DATE_REG_KEY_NAME(RegPath
, 1);
309 GET_DATE_REG_VAL_NAME(RegKeyName
, 1);
310 type
= GET_XXX_REG_VAL_TYPE(DATE
, 1) ? REG_SZ
: REG_DWORD
;
311 pdata
= GET_XXX_REG_VAL_TYPE(DATE
, 1) ? (PVOID
)s
: (PVOID
)&d
;
312 sz
= GET_XXX_REG_VAL_TYPE(DATE
, 1) ? (10+1+1)*sizeof(WCHAR
) : sizeof(d
);
313 if(!(PresentDateMask
& (1 << 1))) {
314 KdPrint(("%ws\n %ws\n", RegPath
, RegKeyName
));
315 RC
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
/*| RTL_REGISTRY_OPTIONAL*/,
318 KdPrint(("status %#x\n", RC
));
322 d
= UDFGlobalData
.iVer
^ XOR_VAR(Version
, 0);
323 swprintf(s
, L
"0x%8.8x\0", d
);
324 GET_VERSION_REG_KEY_NAME(RegPath
, 0);
325 GET_VERSION_REG_VAL_NAME(RegKeyName
, 0);
326 type
= GET_XXX_REG_VAL_TYPE(VERSION
, 0) ? REG_SZ
: REG_DWORD
;
327 pdata
= GET_XXX_REG_VAL_TYPE(VERSION
, 0) ? (PVOID
)s
: (PVOID
)&d
;
328 sz
= GET_XXX_REG_VAL_TYPE(VERSION
, 0) ? (10+1+1)*sizeof(WCHAR
) : sizeof(d
);
329 KdPrint(("%ws\n %ws\n", RegPath
, RegKeyName
));
330 RC
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
/*| RTL_REGISTRY_OPTIONAL*/,
333 KdPrint(("status %#x\n", RC
));
334 d
= UDFGlobalData
.iVer
^ XOR_VAR(Version
, 1);
335 swprintf(s
, L
"0x%8.8x\0", d
);
336 GET_VERSION_REG_KEY_NAME(RegPath
, 1);
337 GET_VERSION_REG_VAL_NAME(RegKeyName
, 1);
338 type
= GET_XXX_REG_VAL_TYPE(VERSION
, 1) ? REG_SZ
: REG_DWORD
;
339 pdata
= GET_XXX_REG_VAL_TYPE(VERSION
, 1) ? (PVOID
)s
: (PVOID
)&d
;
340 sz
= GET_XXX_REG_VAL_TYPE(VERSION
, 1) ? (10+1+1)*sizeof(WCHAR
) : sizeof(d
);
341 KdPrint(("%ws\n %ws\n", RegPath
, RegKeyName
));
342 RC
= RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
/*| RTL_REGISTRY_OPTIONAL*/,
345 KdPrint(("status %#x\n", RC
));
347 #endif //EVALUATION_TIME_LIMIT
349 // initialize the global data resource and remember the fact that
350 // the resource has been initialized
351 RC
= UDFInitializeResourceLite(&(UDFGlobalData
.GlobalDataResource
));
352 ASSERT(NT_SUCCESS(RC
));
353 UDFSetFlag(UDFGlobalData
.UDFFlags
, UDF_DATA_FLAGS_RESOURCE_INITIALIZED
);
355 RC
= UDFInitializeResourceLite(&(UDFGlobalData
.DelayedCloseResource
));
356 ASSERT(NT_SUCCESS(RC
));
357 // UDFSetFlag(UDFGlobalData.UDFFlags, UDF_DATA_FLAGS_RESOURCE_INITIALIZED);
359 // keep a ptr to the driver object sent to us by the I/O Mgr
360 UDFGlobalData
.DriverObject
= DriverObject
;
362 //SeEnableAccessToExports();
364 // initialize the mounted logical volume list head
365 InitializeListHead(&(UDFGlobalData
.VCBQueue
));
367 KdPrint(("UDF: Init memory manager\n"));
368 // Initialize internal memory management
370 try_return(RC
= STATUS_INSUFFICIENT_RESOURCES
);
372 InternalMMInitialized
= TRUE
;
375 // Initialize Deadlock Detector
377 DLDetectInitialized
= TRUE
;
379 // before we proceed with any more initialization, read in
380 // user supplied configurable values ...
383 RtlCopyMemory(&(UDFGlobalData
.SavedRegPath
), RegistryPath
, sizeof(UNICODE_STRING
));
385 UDFGlobalData
.SavedRegPath
.Buffer
= (PWSTR
)MyAllocatePool__(NonPagedPool
, RegistryPath
->Length
+ 2);
386 if(!UDFGlobalData
.SavedRegPath
.Buffer
) try_return (RC
= STATUS_INSUFFICIENT_RESOURCES
);
387 RtlCopyMemory(UDFGlobalData
.SavedRegPath
.Buffer
, RegistryPath
->Buffer
, RegistryPath
->Length
+ 2);
389 RegTGetKeyHandle(NULL
, UDFGlobalData
.SavedRegPath
.Buffer
, &hUdfRootKey
);
391 UDFGlobalData
.UnicodeStrRoot
.Buffer
= L
"\\"; //(PWCHAR)&(UDFGlobalData.UnicodeStrRootBuffer);
392 UDFGlobalData
.UnicodeStrRoot
.Length
= sizeof(WCHAR
);
393 UDFGlobalData
.UnicodeStrRoot
.MaximumLength
= 2*sizeof(WCHAR
);
395 UDFGlobalData
.UnicodeStrSDir
.Buffer
= L
":";
396 UDFGlobalData
.UnicodeStrSDir
.Length
= sizeof(WCHAR
);
397 UDFGlobalData
.UnicodeStrSDir
.MaximumLength
= 2*sizeof(WCHAR
);
399 UDFGlobalData
.AclName
.Buffer
= UDF_SN_NT_ACL
;
400 UDFGlobalData
.AclName
.Length
=
401 (UDFGlobalData
.AclName
.MaximumLength
= sizeof(UDF_SN_NT_ACL
)) - sizeof(WCHAR
);
403 KdPrint(("UDF: Init delayed close queues\n"));
404 #ifdef UDF_DELAYED_CLOSE
405 InitializeListHead( &UDFGlobalData
.DelayedCloseQueue
);
406 InitializeListHead( &UDFGlobalData
.DirDelayedCloseQueue
);
408 ExInitializeWorkItem( &UDFGlobalData
.CloseItem
,
409 (PWORKER_THREAD_ROUTINE
) UDFDelayedClose
,
412 UDFGlobalData
.DelayedCloseCount
= 0;
413 UDFGlobalData
.DirDelayedCloseCount
= 0;
414 #endif //UDF_DELAYED_CLOSE
416 // we should have the registry data (if any), allocate zone memory ...
417 // This is an example of when FSD implementations __try to pre-allocate
418 // some fixed amount of memory to avoid internal fragmentation and/or waiting
419 // later during run-time ...
421 UDFGlobalData
.DefaultZoneSizeInNumStructs
=10;
423 KdPrint(("UDF: Init zones\n"));
424 if (!NT_SUCCESS(RC
= UDFInitializeZones()))
427 KdPrint(("UDF: Init pointers\n"));
428 // initialize the IRP major function table, and the fast I/O table
429 UDFInitializeFunctionPointers(DriverObject
);
431 UDFGlobalData
.CPU_Count
= KeNumberProcessors
;
432 #ifdef EVALUATION_TIME_LIMIT
433 UDFGlobalData
.Saved_j
= 4;
434 #endif //EVALUATION_TIME_LIMIT
436 // create a device object representing the driver itself
437 // so that requests can be targeted to the driver ...
438 // e.g. for a disk-based FSD, "mount" requests will be sent to
439 // this device object by the I/O Manager.\
440 // For a redirector/server, you may have applications
441 // send "special" IOCTL's using this device object ...
443 RtlInitUnicodeString(&DriverDeviceName
, UDF_FS_NAME
);
445 KdPrint(("UDF: Create Driver dev obj\n"));
446 if (!NT_SUCCESS(RC
= IoCreateDevice(
447 DriverObject
, // our driver object
448 sizeof(UDFFS_DEV_EXTENSION
), // don't need an extension for this object
449 &DriverDeviceName
, // name - can be used to "open" the driver
450 // see the book for alternate choices
451 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
452 0, // no special characteristics
453 // do not want this as an exclusive device, though you might
455 &(UDFGlobalData
.UDFDeviceObject
)))) {
456 // failed to create a device object, leave ...
460 FSDevExt
= (PUDFFS_DEV_EXTENSION
)((UDFGlobalData
.UDFDeviceObject
)->DeviceExtension
);
461 // Zero it out (typically this has already been done by the I/O
462 // Manager but it does not hurt to do it again)!
463 RtlZeroMemory(FSDevExt
, sizeof(UDFFS_DEV_EXTENSION
));
465 // Initialize the signature fields
466 FSDevExt
->NodeIdentifier
.NodeType
= UDF_NODE_TYPE_UDFFS_DRVOBJ
;
467 FSDevExt
->NodeIdentifier
.NodeSize
= sizeof(UDFFS_DEV_EXTENSION
);
469 RtlInitUnicodeString(&unicodeDeviceName
, UDF_DOS_FS_NAME
);
470 IoCreateSymbolicLink(&unicodeDeviceName
, &DriverDeviceName
);
472 KdPrint(("UDF: Create CD dev obj\n"));
473 if (!NT_SUCCESS(RC
= UDFCreateFsDeviceObject(UDF_FS_NAME_CD
,
475 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
476 &(UDFGlobalData
.UDFDeviceObject_CD
)))) {
477 // failed to create a device object, leave ...
480 #ifdef UDF_HDD_SUPPORT
481 KdPrint(("UDF: Create HDD dev obj\n"));
482 if (!NT_SUCCESS(RC
= UDFCreateFsDeviceObject(UDF_FS_NAME_HDD
,
484 FILE_DEVICE_DISK_FILE_SYSTEM
,
485 &(UDFGlobalData
.UDFDeviceObject_HDD
)))) {
486 // failed to create a device object, leave ...
489 #endif //UDF_HDD_SUPPORT
491 /* RtlInitUnicodeString(&DriverDeviceName, UDF_FS_NAME_OTHER);
493 if (!NT_SUCCESS(RC = IoCreateDevice(
494 DriverObject, // our driver object
495 0, // don't need an extension for this object
496 &DriverDeviceName, // name - can be used to "open" the driver
497 // see the book for alternate choices
498 FILE_DEVICE_FILE_SYSTEM,
499 0, // no special characteristics
500 // do not want this as an exclusive device, though you might
502 &(UDFGlobalData.UDFDeviceObject_OTHER)))) {
503 // failed to create a device object, leave ...
506 // register the driver with the I/O Manager, pretend as if this is
507 // a physical disk based FSD (or in order words, this FSD manages
508 // logical volumes residing on physical disk drives)
509 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_OTHER);
511 RtlInitUnicodeString(&DriverDeviceName, UDF_FS_NAME_TAPE);
513 if (!NT_SUCCESS(RC = IoCreateDevice(
514 DriverObject, // our driver object
515 0, // don't need an extension for this object
516 &DriverDeviceName, // name - can be used to "open" the driver
517 // see the book for alternate choices
518 FILE_DEVICE_TAPE_FILE_SYSTEM,
519 0, // no special characteristics
520 // do not want this as an exclusive device, though you might
522 &(UDFGlobalData.UDFDeviceObject_TAPE)))) {
523 // failed to create a device object, leave ...
526 // register the driver with the I/O Manager, pretend as if this is
527 // a physical disk based FSD (or in order words, this FSD manages
528 // logical volumes residing on physical disk drives)
529 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_TAPE);
532 if (UDFGlobalData
.UDFDeviceObject_CD
) {
533 KdPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem() for CD\n"));
534 IoRegisterFileSystem(UDFGlobalData
.UDFDeviceObject_CD
);
536 #ifdef UDF_HDD_SUPPORT
537 if (UDFGlobalData
.UDFDeviceObject_HDD
) {
538 KdPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem() for HDD\n"));
539 IoRegisterFileSystem(UDFGlobalData
.UDFDeviceObject_HDD
);
541 #endif // UDF_HDD_SUPPORT
544 KdPrint(("UDF: IoRegisterFsRegistrationChange()\n"));
545 IoRegisterFsRegistrationChange( DriverObject
, (PDRIVER_FS_NOTIFICATION
)UDFFsNotification
);
547 // delay.QuadPart = -10000000;
548 // KeDelayExecutionThread(KernelMode, FALSE, &delay); //10 microseconds
550 #ifdef EVALUATION_TIME_LIMIT
551 // Build Registry Value name for License Key
552 for(i
=0; i
<UDFNumberOfKeys
; i
++) {
554 checksum
[j
] += pUDFKeyList
[i
].d
[j
];
559 for(i
=0; i
<sizeof(UDF_LICENSE_KEY_USER
)-1; i
++) {
560 RegKeyName
[i
] = pRegKeyName0
[(i
*sizeof(UDF_LICENSE_KEY_USER
))] ^ (UCHAR
)(checksum
[i
%4] ^ (checksum
[i
%4] >> 16));
564 // RtlZeroMemory(UDFGlobalData.LicenseKeyW, sizeof(UDFGlobalData.LicenseKeyW));
565 RegTGetStringValue(hUdfRootKey
, NULL
,
566 RegKeyName
, UDFGlobalData
.LicenseKeyW
, (16+1)*sizeof(WCHAR
));
567 // UDFGlobalData.UDFFlags |= UDF_DATA_FLAGS_UNREGISTERED;
569 RegTCloseKeyHandle(hUdfRootKey
);
571 UDFGlobalData
.LicenseKeyW
[16] = 0;
572 // convert WCHAR Key to CHAR key
573 for(i
=0; i
<16; i
++) {
574 LicenseKey
[i
] = (UCHAR
)(UDFGlobalData
.LicenseKeyW
[i
]);
578 UDF_build_hash_by_key(pUDFLongKey
, UDF_LONG_KEY_SIZE
, (PCHAR
)&(UDFGlobalData
.CurrentKeyHash
), LicenseKey
);
579 // check if it is correct
580 for(i
=0; i
<UDFNumberOfKeys
; i
++) {
582 if(pUDFKeyList
[i
].d
[j
] ^ UDFGlobalData
.CurrentKeyHash
.d
[j
]) {
589 if((UDFGlobalData
.Saved_j
= j
) == 4) {
590 UDFGlobalData
.UDFFlags
&= ~UDF_DATA_FLAGS_UNREGISTERED
;
592 if(!(UDFGlobalData
.UDFFlags
& UDF_DATA_FLAGS_UNREGISTERED
)) {
593 UDFGlobalData
.Saved_j
= 4;
596 #else //EVALUATION_TIME_LIMIT
597 delay
.QuadPart
= -10000000; // 1 sec
598 KeDelayExecutionThread(KernelMode
, FALSE
, &delay
);
599 #endif //EVALUATION_TIME_LIMIT
603 /*ExInitializeWorkItem(&RemountWorkQueueItem, UDFRemountAll, NULL);
604 KdPrint(("UDFDriverEntry: create remount thread\n"));
605 ExQueueWorkItem(&RemountWorkQueueItem, DelayedWorkQueue);*/
607 for(CdRomNumber
= 0;true;CdRomNumber
++) {
608 sprintf(deviceNameBuffer
, "\\Device\\CdRom%d", CdRomNumber
);
609 KdPrint(( "UDF: DriverEntry : dismount %s\n", deviceNameBuffer
));
610 RtlInitString(&deviceName
, deviceNameBuffer
);
611 RC
= RtlAnsiStringToUnicodeString(&unicodeCdRomDeviceName
, &deviceName
, TRUE
);
613 if (!NT_SUCCESS(RC
)) {
614 RtlFreeUnicodeString(&unicodeCdRomDeviceName
);
618 RC
= UDFDismountDevice(&unicodeCdRomDeviceName
);
619 RtlFreeUnicodeString(&unicodeCdRomDeviceName
);
621 if (!NT_SUCCESS(RC
)) break;
625 PVOID ModuleBase
= NULL
;
627 // get NTOSKRNL.EXE exports
628 ModuleBase
= CrNtGetModuleBase("NTOSKRNL.EXE");
630 FsRtlNotifyVolumeEvent
= (ptrFsRtlNotifyVolumeEvent
)CrNtGetProcAddress(ModuleBase
, "FsRtlNotifyVolumeEvent");
637 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
638 // we encountered an exception somewhere, eat it up
639 KdPrint(("UDF: exception\n"));
640 RC
= _SEH2_GetExceptionCode();
643 InternalMMInitialized
= FALSE
;
647 // start unwinding if we were unsuccessful
648 if (!NT_SUCCESS(RC
)) {
649 KdPrint(("UDF: failed with status %x\n", RC
));
650 // Now, delete any device objects, etc. we may have created
651 /* if (UDFGlobalData.UDFDeviceObject) {
652 IoDeleteDevice(UDFGlobalData.UDFDeviceObject);
653 UDFGlobalData.UDFDeviceObject = NULL;
656 if (DLDetectInitialized
) DLDFree();
658 if (InternalMMInitialized
) {
661 if (UDFGlobalData
.UDFDeviceObject_CD
) {
662 IoDeleteDevice(UDFGlobalData
.UDFDeviceObject_CD
);
663 UDFGlobalData
.UDFDeviceObject_CD
= NULL
;
665 #ifdef UDF_HDD_SUPPORT
667 if (UDFGlobalData
.UDFDeviceObject_HDD
) {
668 IoDeleteDevice(UDFGlobalData
.UDFDeviceObject_HDD
);
669 UDFGlobalData
.UDFDeviceObject_HDD
= NULL
;
671 #endif // UDF_HDD_SUPPORT
674 if (UDFGlobalData.UDFDeviceObject_OTHER) {
675 IoDeleteDevice(UDFGlobalData.UDFDeviceObject_CD);
676 UDFGlobalData.UDFDeviceObject_CD = NULL;
679 if (UDFGlobalData.UDFDeviceObject_TAPE) {
680 IoDeleteDevice(UDFGlobalData.UDFDeviceObject_CD);
681 UDFGlobalData.UDFDeviceObject_CD = NULL;
684 // free up any memory we might have reserved for zones/lookaside
686 if (UDFGlobalData
.UDFFlags
& UDF_DATA_FLAGS_ZONES_INITIALIZED
) {
690 // delete the resource we may have initialized
691 if (UDFGlobalData
.UDFFlags
& UDF_DATA_FLAGS_RESOURCE_INITIALIZED
) {
692 // un-initialize this resource
693 UDFDeleteResource(&(UDFGlobalData
.GlobalDataResource
));
694 UDFClearFlag(UDFGlobalData
.UDFFlags
, UDF_DATA_FLAGS_RESOURCE_INITIALIZED
);
701 } // end DriverEntry()
705 /*************************************************************************
707 * Function: UDFInitializeFunctionPointers()
710 * Initialize the IRP... function pointer array in the driver object
711 * structure. Also initialize the fast-io function ptr array ...
713 * Expected Interrupt Level (for execution) :
719 *************************************************************************/
722 UDFInitializeFunctionPointers(
723 PDRIVER_OBJECT DriverObject
// created by the I/O sub-system
726 PFAST_IO_DISPATCH PtrFastIoDispatch
= NULL
;
728 // initialize the function pointers for the IRP major
729 // functions that this FSD is prepared to handle ...
730 // NT Version 4.0 has 28 possible functions that a
731 // kernel mode driver can handle.
732 // NT Version 3.51 and before has only 22 such functions,
733 // of which 18 are typically interesting to most FSD's.
735 // The only interesting new functions that a FSD might
736 // want to respond to beginning with Version 4.0 are the
737 // IRP_MJ_QUERY_QUOTA and the IRP_MJ_SET_QUOTA requests.
739 // The code below does not handle quota manipulation, neither
740 // does the NT Version 4.0 operating system (or I/O Manager).
741 // However, you should be on the lookout for any such new
742 // functionality that the FSD might have to implement in
745 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = UDFCreate
;
746 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = UDFClose
;
747 DriverObject
->MajorFunction
[IRP_MJ_READ
] = UDFRead
;
748 #ifndef UDF_READ_ONLY_BUILD
749 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = UDFWrite
;
750 #endif //UDF_READ_ONLY_BUILD
752 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] = UDFFileInfo
;
753 #ifndef UDF_READ_ONLY_BUILD
754 DriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] = UDFFileInfo
;
755 #endif //UDF_READ_ONLY_BUILD
757 #ifndef UDF_READ_ONLY_BUILD
758 DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
] = UDFFlush
;
759 #endif //UDF_READ_ONLY_BUILD
760 // To implement support for querying and modifying volume attributes
761 // (volume information query/set operations), enable initialization
762 // of the following two function pointers and then implement the supporting
764 DriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] = UDFQueryVolInfo
;
765 #ifndef UDF_READ_ONLY_BUILD
767 DriverObject
->MajorFunction
[IRP_MJ_SET_VOLUME_INFORMATION
] = UDFSetVolInfo
;
769 #endif //UDF_READ_ONLY_BUILD
770 DriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] = UDFDirControl
;
771 // To implement support for file system IOCTL calls, enable initialization
772 // of the following function pointer and implement appropriate support.
773 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = UDFFSControl
;
774 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = UDFDeviceControl
;
775 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = UDFShutdown
;
776 // For byte-range lock support, enable initialization of the following
777 // function pointer and implement appropriate support.
778 DriverObject
->MajorFunction
[IRP_MJ_LOCK_CONTROL
] = UDFLockControl
;
779 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = UDFCleanup
;
780 #ifdef UDF_HANDLE_EAS
781 DriverObject
->MajorFunction
[IRP_MJ_QUERY_EA
] = UDFQuerySetEA
;
782 #ifndef UDF_READ_ONLY_BUILD
783 DriverObject
->MajorFunction
[IRP_MJ_SET_EA
] = UDFQuerySetEA
;
784 #endif //UDF_READ_ONLY_BUILD
785 #endif //UDF_HANDLE_EAS
786 // If the FSD supports security attributes, we should provide appropriate
787 // dispatch entry points and initialize the function pointers as given below.
789 #ifdef UDF_ENABLE_SECURITY
790 DriverObject
->MajorFunction
[IRP_MJ_QUERY_SECURITY
] = UDFGetSecurity
;
791 #ifndef UDF_READ_ONLY_BUILD
793 DriverObject
->MajorFunction
[IRP_MJ_SET_SECURITY
] = UDFSetSecurity
;
795 #endif //UDF_READ_ONLY_BUILD
796 #endif //UDF_ENABLE_SECURITY
798 // if(MajorVersion >= 0x05) {
800 // DriverObject->MajorFunction[IRP_MJ_PNP] = UDFPnp;
803 // Now, it is time to initialize the fast-io stuff ...
804 PtrFastIoDispatch
= DriverObject
->FastIoDispatch
= &(UDFGlobalData
.UDFFastIoDispatch
);
806 // initialize the global fast-io structure
807 // NOTE: The fast-io structure has undergone a substantial revision
808 // in Windows NT Version 4.0. The structure has been extensively expanded.
809 // Therefore, if the driver needs to work on both V3.51 and V4.0+,
810 // we will have to be able to distinguish between the two versions at compile time.
812 RtlZeroMemory(PtrFastIoDispatch
, sizeof(FAST_IO_DISPATCH
));
814 PtrFastIoDispatch
->SizeOfFastIoDispatch
= sizeof(FAST_IO_DISPATCH
);
815 PtrFastIoDispatch
->FastIoCheckIfPossible
= UDFFastIoCheckIfPossible
;
816 PtrFastIoDispatch
->FastIoRead
= FsRtlCopyRead
;
817 #ifndef UDF_READ_ONLY_BUILD
818 PtrFastIoDispatch
->FastIoWrite
= UDFFastIoCopyWrite
/*FsRtlCopyWrite*/;
819 #endif //UDF_READ_ONLY_BUILD
820 PtrFastIoDispatch
->FastIoQueryBasicInfo
= UDFFastIoQueryBasicInfo
;
821 PtrFastIoDispatch
->FastIoQueryStandardInfo
= UDFFastIoQueryStdInfo
;
822 PtrFastIoDispatch
->FastIoLock
= UDFFastLock
; // Lock
823 PtrFastIoDispatch
->FastIoUnlockSingle
= UDFFastUnlockSingle
; // UnlockSingle
824 PtrFastIoDispatch
->FastIoUnlockAll
= UDFFastUnlockAll
; // UnlockAll
825 PtrFastIoDispatch
->FastIoUnlockAllByKey
= (unsigned char (__stdcall
*)(struct _FILE_OBJECT
*,
826 PVOID
,unsigned long,struct _IO_STATUS_BLOCK
*,struct _DEVICE_OBJECT
*))UDFFastUnlockAllByKey
; // UnlockAllByKey
828 PtrFastIoDispatch
->AcquireFileForNtCreateSection
= UDFFastIoAcqCreateSec
;
829 PtrFastIoDispatch
->ReleaseFileForNtCreateSection
= UDFFastIoRelCreateSec
;
831 // PtrFastIoDispatch->FastIoDeviceControl = UDFFastIoDeviceControl;
833 // the remaining are only valid under NT Version 4.0 and later
834 #if(_WIN32_WINNT >= 0x0400)
836 PtrFastIoDispatch
->FastIoQueryNetworkOpenInfo
= UDFFastIoQueryNetInfo
;
838 PtrFastIoDispatch
->AcquireForModWrite
= UDFFastIoAcqModWrite
;
839 PtrFastIoDispatch
->ReleaseForModWrite
= UDFFastIoRelModWrite
;
840 PtrFastIoDispatch
->AcquireForCcFlush
= UDFFastIoAcqCcFlush
;
841 PtrFastIoDispatch
->ReleaseForCcFlush
= UDFFastIoRelCcFlush
;
843 /* // MDL functionality
845 PtrFastIoDispatch->MdlRead = UDFFastIoMdlRead;
846 PtrFastIoDispatch->MdlReadComplete = UDFFastIoMdlReadComplete;
847 PtrFastIoDispatch->PrepareMdlWrite = UDFFastIoPrepareMdlWrite;
848 PtrFastIoDispatch->MdlWriteComplete = UDFFastIoMdlWriteComplete;*/
850 // this FSD does not support compressed read/write functionality,
851 // NTFS does, and if we design a FSD that can provide such functionality,
852 // we should consider initializing the fast io entry points for reading
853 // and/or writing compressed data ...
854 #endif // (_WIN32_WINNT >= 0x0400)
856 // last but not least, initialize the Cache Manager callback functions
857 // which are used in CcInitializeCacheMap()
859 UDFGlobalData
.CacheMgrCallBacks
.AcquireForLazyWrite
= UDFAcqLazyWrite
;
860 UDFGlobalData
.CacheMgrCallBacks
.ReleaseFromLazyWrite
= UDFRelLazyWrite
;
861 UDFGlobalData
.CacheMgrCallBacks
.AcquireForReadAhead
= UDFAcqReadAhead
;
862 UDFGlobalData
.CacheMgrCallBacks
.ReleaseFromReadAhead
= UDFRelReadAhead
;
864 DriverObject
->DriverUnload
= UDFDriverUnload
;
867 } // end UDFInitializeFunctionPointers()
870 UDFCreateFsDeviceObject(
872 PDRIVER_OBJECT DriverObject
,
873 DEVICE_TYPE DeviceType
,
874 PDEVICE_OBJECT
*DeviceObject
877 NTSTATUS RC
= STATUS_SUCCESS
;
878 UNICODE_STRING DriverDeviceName
;
879 PUDFFS_DEV_EXTENSION FSDevExt
;
880 RtlInitUnicodeString(&DriverDeviceName
, FsDeviceName
);
881 *DeviceObject
= NULL
;
883 KdPrint(("UDFCreateFsDeviceObject: create dev\n"));
885 if (!NT_SUCCESS(RC
= IoCreateDevice(
886 DriverObject
, // our driver object
887 sizeof(UDFFS_DEV_EXTENSION
), // don't need an extension for this object
888 &DriverDeviceName
, // name - can be used to "open" the driver
889 // see the book for alternate choices
891 0, // no special characteristics
892 // do not want this as an exclusive device, though you might
895 // failed to create a device object, leave ...
898 FSDevExt
= (PUDFFS_DEV_EXTENSION
)((*DeviceObject
)->DeviceExtension
);
899 // Zero it out (typically this has already been done by the I/O
900 // Manager but it does not hurt to do it again)!
901 RtlZeroMemory(FSDevExt
, sizeof(UDFFS_DEV_EXTENSION
));
903 // Initialize the signature fields
904 FSDevExt
->NodeIdentifier
.NodeType
= UDF_NODE_TYPE_UDFFS_DEVOBJ
;
905 FSDevExt
->NodeIdentifier
.NodeSize
= sizeof(UDFFS_DEV_EXTENSION
);
906 // register the driver with the I/O Manager, pretend as if this is
907 // a physical disk based FSD (or in order words, this FSD manages
908 // logical volumes residing on physical disk drives)
909 /* KdPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem()\n"));
910 IoRegisterFileSystem(*DeviceObject);*/
912 } // end UDFCreateFsDeviceObject()
917 PUNICODE_STRING unicodeCdRomDeviceName
921 IO_STATUS_BLOCK IoStatus
;
922 HANDLE NtFileHandle
= (HANDLE
)-1;
923 OBJECT_ATTRIBUTES ObjectAttributes
;
924 NOTIFY_MEDIA_CHANGE_USER_IN buffer
= { 0 };
925 PFILE_FS_ATTRIBUTE_INFORMATION Buffer
;
929 Buffer
= (PFILE_FS_ATTRIBUTE_INFORMATION
)MyAllocatePool__(NonPagedPool
,sizeof(FILE_FS_ATTRIBUTE_INFORMATION
)+2*sizeof(UDF_FS_TITLE_DVDRAM
));
930 if (!Buffer
) try_return(RC
= STATUS_INSUFFICIENT_RESOURCES
);
932 InitializeObjectAttributes ( &ObjectAttributes
,
933 unicodeCdRomDeviceName
,
934 OBJ_CASE_INSENSITIVE
,
938 KdPrint(("\n*** UDFDismountDevice: Create\n"));
939 RC
= ZwCreateFile( &NtFileHandle
,
944 FILE_ATTRIBUTE_NORMAL
,
947 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
,
952 if (!NT_SUCCESS(RC
)) try_return(RC
);
954 KdPrint(("\n*** UDFDismountDevice: QueryVolInfo\n"));
955 RC
= ZwQueryVolumeInformationFile( NtFileHandle
,
958 sizeof(FILE_FS_ATTRIBUTE_INFORMATION
)+2*sizeof(UDF_FS_TITLE_DVDRAM
),
959 FileFsAttributeInformation
);
961 #define UDF_CHECK_FS_NAME(name) \
962 (Buffer->FileSystemNameLength+sizeof(WCHAR) == sizeof(name) && \
963 DbgCompareMemory(&Buffer->FileSystemName[0],name , sizeof(name)) == sizeof(name))
965 if (NT_SUCCESS(RC
) &&
966 (UDF_CHECK_FS_NAME(UDF_FS_TITLE_CDR
) ||
967 UDF_CHECK_FS_NAME(UDF_FS_TITLE_CDRW
) ||
968 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDR
) ||
969 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDRW
) ||
970 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDpR
) ||
971 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDpRW
) ||
972 UDF_CHECK_FS_NAME(UDF_FS_TITLE_DVDRAM
) )) try_return(STATUS_SUCCESS
);
974 KdPrint(("\n*** UDFDismountDevice: LockVolume\n"));
975 RC
= ZwFsControlFile(NtFileHandle
,
986 if (!NT_SUCCESS(RC
)) try_return(RC
);
988 KdPrint(("\n*** UDFDismountDevice: DismountVolume\n"));
989 RC
= ZwFsControlFile(NtFileHandle
,
994 FSCTL_DISMOUNT_VOLUME
,
1000 if (!NT_SUCCESS(RC
)) try_return(RC
);
1002 KdPrint(("\n*** UDFDismountDevice: NotifyMediaChange\n"));
1003 RC
= ZwDeviceIoControlFile(NtFileHandle
,
1008 IOCTL_CDRW_NOTIFY_MEDIA_CHANGE
,
1014 if (!NT_SUCCESS(RC
)) try_return(RC
);
1017 KdPrint(("\n*** UDFDismountDevice: UnlockVolume\n"));
1018 RC
= ZwFsControlFile(NtFileHandle
,
1023 FSCTL_UNLOCK_VOLUME
,
1029 KdPrint(("\n*** UDFDismountDevice: Close\n"));
1030 ZwClose( NtFileHandle
);
1032 NtFileHandle
= (HANDLE
)-1;
1034 KdPrint(("\n*** UDFDismountDevice: Create 2\n"));
1035 RC
= ZwCreateFile( &NtFileHandle
,
1040 FILE_ATTRIBUTE_NORMAL
,
1043 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
,
1050 if (Buffer
) MyFreePool__(Buffer
);
1051 if (NtFileHandle
!= (HANDLE
)-1) ZwClose( NtFileHandle
);
1054 KdPrint(("\n*** UDFDismountDevice: RC=%x\n",RC
));
1062 IN PDEVICE_OBJECT DeviceObject
,
1068 Routine Description:
1070 This routine is invoked whenever a file system has either registered or
1071 unregistered itself as an active file system.
1073 For the former case, this routine creates a device object and attaches it
1074 to the specified file system's device object. This allows this driver
1075 to filter all requests to that file system.
1077 For the latter case, this file system's device object is located,
1078 detached, and deleted. This removes this file system as a filter for
1079 the specified file system.
1083 DeviceObject - Pointer to the file system's device object.
1085 FsActive - bolean indicating whether the file system has registered
1086 (TRUE) or unregistered (FALSE) itself as an active file system.
1095 // Begin by determine whether or not the file system is a cdrom-based file
1096 // system. If not, then this driver is not concerned with it.
1097 if (!FsRegistered
||
1098 DeviceObject
->DeviceType
!= FILE_DEVICE_CD_ROM_FILE_SYSTEM
) {
1102 // Begin by determining whether this file system is registering or
1103 // unregistering as an active file system.
1105 && UDFGlobalData
.UDFDeviceObject_CD
!= DeviceObject
1106 #ifdef UDF_HDD_SUPPORT
1107 && UDFGlobalData
.UDFDeviceObject_HDD
!= DeviceObject
1108 #endif // UDF_HDD_SUPPORT
1110 KdPrint(("\n*** UDFFSNotification \n\n"));
1112 // Acquire GlobalDataResource
1113 UDFAcquireResourceExclusive(&(UDFGlobalData
.GlobalDataResource
), TRUE
);
1115 if(FsNotification_ThreadId
!= PsGetCurrentThreadId()) {
1117 FsNotification_ThreadId
= PsGetCurrentThreadId();
1119 IoUnregisterFileSystem(UDFGlobalData
.UDFDeviceObject_CD
);
1120 IoRegisterFileSystem(UDFGlobalData
.UDFDeviceObject_CD
);
1122 #ifdef UDF_HDD_SUPPORT
1123 IoUnregisterFileSystem(UDFGlobalData
.UDFDeviceObject_HDD
);
1124 IoRegisterFileSystem(UDFGlobalData
.UDFDeviceObject_HDD
);
1125 #endif // UDF_HDD_SUPPORT
1127 FsNotification_ThreadId
= (HANDLE
)(-1);
1130 KdPrint(("\n*** recursive UDFFSNotification call,\n can't become top-level UDF FSD \n\n"));
1133 // Release the global resource.
1134 UDFReleaseResource( &(UDFGlobalData
.GlobalDataResource
) );
1144 NTSTATUS RC = STATUS_SUCCESS;
1146 CCHAR deviceNameBuffer[MAXIMUM_FILENAME_LENGTH];
1147 ANSI_STRING deviceName;
1148 UNICODE_STRING unicodeCdRomDeviceName;
1149 LARGE_INTEGER delay;
1151 /* delay.QuadPart = -80*10000000;
1152 KeDelayExecutionThread(KernelMode, FALSE, &delay); //10 seconds*/
1154 /* for(CdRomNumber = 0;true;CdRomNumber++) {
1155 sprintf(deviceNameBuffer, "\\Device\\CdRom%d", CdRomNumber);
1156 KdPrint(( "UDF: UDFRemountAll : dismount %s\n", deviceNameBuffer));
1157 RtlInitString(&deviceName, deviceNameBuffer);
1158 RC = RtlAnsiStringToUnicodeString(&unicodeCdRomDeviceName, &deviceName, TRUE);
1160 if (!NT_SUCCESS(RC)) {
1161 RtlFreeUnicodeString(&unicodeCdRomDeviceName);
1165 RC = UDFDismountDevice(&unicodeCdRomDeviceName);
1166 RtlFreeUnicodeString(&unicodeCdRomDeviceName);
1168 if (!NT_SUCCESS(RC)) break;
1173 #ifdef EVALUATION_TIME_LIMIT
1176 UDFGetInstallVersion(
1188 KdPrint((KD_PREFIX
"UDFGetInstallVersion:\n"));
1190 (*iVer
) = UDF_CURRENT_BUILD
;
1191 for(j
=0; j
<UDF_INSTALL_INFO_LOCATIONS
; j
++) {
1192 RtlZeroMemory(Str
, sizeof(Str
));
1194 case 0: GET_VERSION_REG_KEY_NAME(RegPath
, 0); break;
1195 case 1: GET_VERSION_REG_KEY_NAME(RegPath
, 1); break;
1199 case 0: GET_VERSION_REG_VAL_NAME(RegVal
, 0); break;
1200 case 1: GET_VERSION_REG_VAL_NAME(RegVal
, 1); break;
1204 type
= GET_XXX_REG_VAL_TYPE(VERSION
, 1);
1206 type
= GET_XXX_REG_VAL_TYPE(VERSION
, 0);
1209 RegTGetDwordValue(NULL
, RegPath
, RegVal
, &v
)) {
1211 KdPrint((KD_PREFIX
"val: %x\n", v
));
1216 RegTGetStringValue(NULL
, RegPath
, RegVal
,
1220 for(i
=2; i
<10; i
++) {
1221 if(Str
[i
] >= 'a' && Str
[i
] <= 'f') {
1222 a
= 10 + Str
[i
] - 'a';
1226 KdPrint((KD_PREFIX
"val: %x\n", a
));
1232 case 0: v
^= XOR_VAR(Version
, 0); break;
1233 case 1: v
^= XOR_VAR(Version
, 1); break;
1237 if((*iVer
) == -1 || (*iVer
) < v
) {
1240 UDFGlobalData
.iVer
= (*iVer
);
1243 UDFGlobalData
.iVer
= (*iVer
);
1244 /* if(UDFGlobalData.iVer == -1)
1246 KdPrint((KD_PREFIX
"ret val: %x\n", *iVer
));
1247 if((*iVer
) > UDF_CURRENT_BUILD
) {
1251 } // end UDFGetInstallVersion()
1266 KdPrint((KD_PREFIX
"UDFGetInstallTime:\n"));
1269 for(j
=0; j
<UDF_INSTALL_INFO_LOCATIONS
; j
++) {
1270 RtlZeroMemory(Str
, sizeof(Str
));
1272 case 0: GET_DATE_REG_KEY_NAME(RegPath
, 0); break;
1273 case 1: GET_DATE_REG_KEY_NAME(RegPath
, 1); break;
1277 case 0: GET_DATE_REG_VAL_NAME(RegVal
, 0); break;
1278 case 1: GET_DATE_REG_VAL_NAME(RegVal
, 1); break;
1282 type
= GET_XXX_REG_VAL_TYPE(DATE
, 1);
1284 type
= GET_XXX_REG_VAL_TYPE(DATE
, 0);
1287 RegTGetDwordValue(NULL
, RegPath
, RegVal
, &v
)) {
1289 KdPrint((KD_PREFIX
"val: %x\n", v
));
1294 RegTGetStringValue(NULL
, RegPath
, RegVal
,
1298 for(i
=2; i
<10; i
++) {
1299 if(Str
[i
] >= 'a' && Str
[i
] <= 'f') {
1300 a
= 10 + Str
[i
] - 'a';
1304 KdPrint((KD_PREFIX
"val: %x\n", a
));
1310 case 0: v
^= XOR_VAR(Date
, 0); break;
1311 case 1: v
^= XOR_VAR(Date
, 1); break;
1313 PresentDateMask
|= 0x00000001 << j
;
1316 if((*iTime
) == -1 || (*iTime
) < v
) {
1319 UDFGlobalData
.iTime
= (*iTime
);
1322 UDFGlobalData
.iTime
= (*iTime
);
1323 if(UDFGlobalData
.iTime
== -1) {
1325 LARGE_INTEGER cTime
;
1326 KeQuerySystemTime((PLARGE_INTEGER
)&cTime
);
1328 cTime
.QuadPart
/= (10*1000*1000);
1329 cTime
.QuadPart
/= (60*60*24);
1331 KdPrint((KD_PREFIX
"cTime = %x, jTime = %x\n", cTime
.LowPart
, TIME_JAN_1_2003
));
1332 if(cTime
.QuadPart
< TIME_JAN_1_2003
) {
1333 KdPrint((KD_PREFIX
"Eval time expired (1)\n"));
1334 UDFGlobalData
.UDFFlags
|= UDF_DATA_FLAGS_UNREGISTERED
;
1336 cTime
.LowPart
-= TIME_JAN_1_2003
;
1337 KdPrint(("cTime = %x\n", cTime
.LowPart
));
1339 UDFGlobalData
.iTime
= (*iTime
) = cTime
.LowPart
;
1342 UDFGlobalData
.iTime
= (*iTime
);
1343 KdPrint((KD_PREFIX
"ret val: %x\n", *iTime
));
1345 } // end UDFGetInstallTime()
1360 KdPrint((KD_PREFIX
"UDFGetTrialEnd:\n"));
1363 for(j
=0; j
<UDF_INSTALL_INFO_LOCATIONS
; j
++) {
1364 RtlZeroMemory(Str
, sizeof(Str
));
1366 case 0: GET_TRIAL_REG_KEY_NAME(RegPath
, 0); break;
1367 case 1: GET_TRIAL_REG_KEY_NAME(RegPath
, 1); break;
1371 case 0: GET_TRIAL_REG_VAL_NAME(RegVal
, 0); break;
1372 case 1: GET_TRIAL_REG_VAL_NAME(RegVal
, 1); break;
1376 type
= GET_XXX_REG_VAL_TYPE(TRIAL
, 1);
1378 type
= GET_XXX_REG_VAL_TYPE(TRIAL
, 0);
1381 RegTGetDwordValue(NULL
, RegPath
, RegVal
, &v
)) {
1383 KdPrint((KD_PREFIX
"val: %x\n", v
));
1388 RegTGetStringValue(NULL
, RegPath
, RegVal
,
1392 for(i
=2; i
<10; i
++) {
1393 if(Str
[i
] >= 'a' && Str
[i
] <= 'f') {
1394 a
= 10 + Str
[i
] - 'a';
1398 KdPrint((KD_PREFIX
"val: %x\n", a
));
1404 case 0: v
^= XOR_VAR(TrialEnd
, 0); break;
1405 case 1: v
^= XOR_VAR(TrialEnd
, 1); break;
1410 if(UDFGlobalData
.iTrial
= (*iTrial
)) {
1416 } // end UDFGetTrialEnd()
1418 #endif //EVALUATION_TRIAL_LIMIT