00059 :
00060
00061 Open/
Create Primary, Alternate, and Log files
for Hives.
00062
00063
BaseName is some name like
"\winnt\system32\config\system".
00064 Extension
is ".alt" or
".log" or
NULL.
00065
00066 If
extension is NULL skip secondary work.
00067
00068 If
extension is .alt or .log, open/create a secondary
file
00069 (e.g.
"\winnt\system32\config\system.alt")
00070
00071 If
extension is .log, open secondary
for buffered I/O,
else,
00072 open
for non-buffered I/O. Primary always uses non-buffered I/O.
00073
00074 If primary
is newly created, supersede secondary. If secondary
00075 does not exist, simply create (other code will complain
if Log
00076 is needed but does not exist.)
00077
00078 WARNING: If Secondary handle is NULL, you have no log
00079 or alternate!
00080
00081 Arguments:
00082
00083 BaseName - unicode string of base hive file, must have space
for
00084 extension
if that is used.
00085
00086 Extension - unicode type extension of secondary file, including
00087 the leading
"."
00088
00089 Primary - will get handle to primary file
00090
00091 Secondary - will get handle to secondary, or NULL
00092
00093 PrimaryDisposition - STATUS_SUCCESS or STATUS_CREATED, of primary
file.
00094
00095 SecondaryDisposition - STATUS_SUCCESS or STATUS_CREATED, of secondary
file.
00096
00097 CreateAllowed -
if TRUE will create nonexistent primary,
if FALSE will
00098 fail
if primary does not exist. no effect on log
00099
00100 MarkAsSystemHive -
if TRUE will call into file system to mark
this
00101 as a critical system hive.
00102
00103 ClusterSize -
if not NULL, will compute and
return the appropriate
00104 cluster size
for the primary
file.
00105
00106 Return Value:
00107
00108 status -
if status is success, Primay succeeded, check Secondary
00109 value to see
if it succeeded.
00110
00111 --*/
00112 {
00113 IO_STATUS_BLOCK IoStatus;
00114 IO_STATUS_BLOCK FsctlIoStatus;
00115 FILE_FS_SIZE_INFORMATION FsSizeInformation;
00116 ULONG Cluster;
00117 ULONG CreateDisposition;
00118 OBJECT_ATTRIBUTES ObjectAttributes;
00119 NTSTATUS status;
00120 UNICODE_STRING ExtName;
00121 UNICODE_STRING WorkName;
00122 PVOID WorkBuffer;
00123 USHORT NameSize;
00124 ULONG IoFlags;
00125 ULONG AttributeFlags;
00126 USHORT CompressionState;
00127 HANDLE hEvent;
00128
PKEVENT pEvent;
00129
00130
00131
00132
00133 status =
CmpCreateEvent(NotificationEvent, &hEvent, &pEvent);
00134
if (!
NT_SUCCESS(status)) {
00135
return(status);
00136 }
00137
00138
00139
00140
00141
WorkName.Length = 0;
00142
WorkName.MaximumLength = 0;
00143
WorkName.Buffer = NULL;
00144 WorkBuffer = NULL;
00145
00146 NameSize =
BaseName->Length;
00147 if (ARGUMENT_PRESENT(Extension)) {
00148 NameSize += (wcslen(Extension)+1) *
sizeof(WCHAR);
00149 WorkBuffer =
ExAllocatePool(PagedPool, NameSize);
00150
WorkName.Buffer = WorkBuffer;
00151 if (WorkBuffer == NULL) {
00152
ObDereferenceObject(pEvent);
00153 ZwClose(hEvent);
00154
return STATUS_NO_MEMORY;
00155 }
00156
WorkName.MaximumLength = NameSize;
00157
RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)BaseName);
00158 }
else {
00159 WorkName = *BaseName;
00160 }
00161
00162
00163
00164
00165
00166 InitializeObjectAttributes(
00167 &ObjectAttributes,
00168 &WorkName,
00169 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
00170 NULL,
00171 NULL
00172 );
00173
00174
if (CreateAllowed) {
00175 CreateDisposition = FILE_OPEN_IF;
00176 }
else {
00177 CreateDisposition = FILE_OPEN;
00178 }
00179
00180
ASSERT_PASSIVE_LEVEL();
00181
00182 status =
ZwCreateFile(
00183 Primary,
00184 FILE_READ_DATA | FILE_WRITE_DATA,
00185 &ObjectAttributes,
00186 &IoStatus,
00187 NULL,
00188 FILE_ATTRIBUTE_NORMAL,
00189 0,
00190 CreateDisposition,
00191 FILE_NO_INTERMEDIATE_BUFFERING |
00192 FILE_OPEN_FOR_BACKUP_INTENT |
00193 FILE_NO_COMPRESSION,
00194 NULL,
00195 0
00196 );
00197
if (status == STATUS_ACCESS_DENIED) {
00198
00199
00200
00201
00202
00203
00204
00205 status =
CmpOpenFileWithExtremePrejudice(Primary,
00206 &ObjectAttributes,
00207 FILE_NO_INTERMEDIATE_BUFFERING |
00208 FILE_OPEN_FOR_BACKUP_INTENT |
00209 FILE_NO_COMPRESSION,
00210 FILE_ATTRIBUTE_NORMAL);
00211 }
00212
00213
if ((MarkAsSystemHive) &&
00214 (
NT_SUCCESS(status))) {
00215
00216
ASSERT_PASSIVE_LEVEL();
00217 status = ZwFsControlFile(*Primary,
00218 hEvent,
00219 NULL,
00220 NULL,
00221 &FsctlIoStatus,
00222 FSCTL_MARK_AS_SYSTEM_HIVE,
00223 NULL,
00224 0,
00225 NULL,
00226 0);
00227
if (status == STATUS_PENDING) {
00228
KeWaitForSingleObject(pEvent,
00229 Executive,
00230 KernelMode,
00231 FALSE,
00232 NULL);
00233 status = FsctlIoStatus.Status;
00234 }
00235
00236
00237
00238
00239
00240
if (status == STATUS_INVALID_DEVICE_REQUEST) {
00241 status = STATUS_SUCCESS;
00242
00243 }
else if (!
NT_SUCCESS(status)) {
00244 ZwClose(*Primary);
00245 }
00246 }
00247
00248
if (!
NT_SUCCESS(status)) {
00249
CMLOG(CML_BUGCHECK, CMS_INIT_ERROR) {
00250 KdPrint((
"CMINIT: CmpOpenHiveFile: "));
00251 KdPrint((
"\tPrimary Open/Create failed for:\n"));
00252 KdPrint((
"\t%wZ\n", &WorkName));
00253 KdPrint((
"\tstatus = %08lx\n", status));
00254 }
00255
if (WorkBuffer !=
NULL) {
00256
ExFreePool(WorkBuffer);
00257 }
00258
ObDereferenceObject(pEvent);
00259 ZwClose(hEvent);
00260
return status;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 CompressionState = 0;
00273
ASSERT_PASSIVE_LEVEL();
00274 status = ZwFsControlFile(*Primary,
00275 hEvent,
00276 NULL,
00277 NULL,
00278 &FsctlIoStatus,
00279 FSCTL_SET_COMPRESSION,
00280 &CompressionState,
00281
sizeof(CompressionState),
00282 NULL,
00283 0);
00284
if (status == STATUS_PENDING) {
00285
KeWaitForSingleObject(pEvent,
00286 Executive,
00287 KernelMode,
00288 FALSE,
00289 NULL);
00290 }
00291
00292 *PrimaryDisposition = (ULONG) IoStatus.Information;
00293
00294
if (ARGUMENT_PRESENT(ClusterSize)) {
00295
00296
ASSERT_PASSIVE_LEVEL();
00297 status = ZwQueryVolumeInformationFile(*Primary,
00298 &IoStatus,
00299 &FsSizeInformation,
00300
sizeof(FILE_FS_SIZE_INFORMATION),
00301 FileFsSizeInformation);
00302
if (!
NT_SUCCESS(status)) {
00303
ObDereferenceObject(pEvent);
00304 ZwClose(hEvent);
00305
return(status);
00306 }
00307
if (FsSizeInformation.BytesPerSector >
HBLOCK_SIZE) {
00308
CMLOG(CML_BUGCHECK, CMS_INIT_ERROR) {
00309 KdPrint((
"CmpOpenHiveFiles: sectorsize %lx > HBLOCK_SIZE\n"));
00310 }
00311
ObDereferenceObject(pEvent);
00312 ZwClose(hEvent);
00313
return(STATUS_CANNOT_LOAD_REGISTRY_FILE);
00314 }
00315
00316 Cluster = FsSizeInformation.BytesPerSector /
HSECTOR_SIZE;
00317 *ClusterSize = (Cluster < 1) ? 1 : Cluster;
00318
00319 }
00320
00321
if ( ! ARGUMENT_PRESENT(Extension)) {
00322
if (WorkBuffer !=
NULL) {
00323
ExFreePool(WorkBuffer);
00324 }
00325
ObDereferenceObject(pEvent);
00326 ZwClose(hEvent);
00327
return STATUS_SUCCESS;
00328 }
00329
00330
00331
00332
00333 CreateDisposition = FILE_OPEN_IF;
00334
if (*PrimaryDisposition == FILE_CREATED) {
00335 CreateDisposition = FILE_SUPERSEDE;
00336 }
00337
00338
RtlInitUnicodeString(&ExtName,Extension);
00339 status =
RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&ExtName);
00340
00341 InitializeObjectAttributes(&ObjectAttributes,
00342 &WorkName,
00343 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
00344 NULL,
00345 NULL);
00346
00347 IoFlags = FILE_NO_COMPRESSION;
00348
if (_wcsnicmp(Extension, L
".log", 4) != 0) {
00349 IoFlags |= FILE_NO_INTERMEDIATE_BUFFERING;
00350 AttributeFlags = FILE_ATTRIBUTE_NORMAL;
00351 }
else {
00352 AttributeFlags = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN;
00353 }
00354
00355
ASSERT_PASSIVE_LEVEL();
00356 status =
ZwCreateFile(
00357 Secondary,
00358 FILE_READ_DATA | FILE_WRITE_DATA,
00359 &ObjectAttributes,
00360 &IoStatus,
00361 NULL,
00362 AttributeFlags,
00363 0,
00364 CreateDisposition,
00365 IoFlags,
00366 NULL,
00367 0
00368 );
00369
00370
if (status == STATUS_ACCESS_DENIED) {
00371
00372
00373
00374
00375
00376
00377
00378 status =
CmpOpenFileWithExtremePrejudice(Secondary,
00379 &ObjectAttributes,
00380 IoFlags,
00381 AttributeFlags);
00382 }
00383
00384
if ((MarkAsSystemHive) &&
00385 (
NT_SUCCESS(status))) {
00386
00387
ASSERT_PASSIVE_LEVEL();
00388 status = ZwFsControlFile(*Secondary,
00389 hEvent,
00390 NULL,
00391 NULL,
00392 &FsctlIoStatus,
00393 FSCTL_MARK_AS_SYSTEM_HIVE,
00394 NULL,
00395 0,
00396 NULL,
00397 0);
00398
if (status == STATUS_PENDING) {
00399
KeWaitForSingleObject(pEvent,
00400 Executive,
00401 KernelMode,
00402 FALSE,
00403 NULL);
00404 status = FsctlIoStatus.Status;
00405 }
00406
00407
00408
00409
00410
if (status == STATUS_INVALID_DEVICE_REQUEST) {
00411 status = STATUS_SUCCESS;
00412
00413 }
else if (!
NT_SUCCESS(status)) {
00414
00415 ZwClose(*Secondary);
00416 }
00417 }
00418
00419
if (!
NT_SUCCESS(status)) {
00420
CMLOG(CML_BUGCHECK, CMS_INIT_ERROR) {
00421 KdPrint((
"CMINIT: CmpOpenHiveFile: "));
00422 KdPrint((
"\tSecondary Open/Create failed for:\n"));
00423 KdPrint((
"\t%wZ\n", &WorkName));
00424 KdPrint((
"\tstatus = %08lx\n", status));
00425 }
00426 *Secondary =
NULL;
00427 }
00428
00429 *SecondaryDisposition = (ULONG) IoStatus.Information;
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 CompressionState = 0;
00441
00442
ASSERT_PASSIVE_LEVEL();
00443 status = ZwFsControlFile(*Secondary,
00444 hEvent,
00445 NULL,
00446 NULL,
00447 &FsctlIoStatus,
00448 FSCTL_SET_COMPRESSION,
00449 &CompressionState,
00450
sizeof(CompressionState),
00451 NULL,
00452 0);
00453
if (status == STATUS_PENDING) {
00454
KeWaitForSingleObject(pEvent,
00455 Executive,
00456 KernelMode,
00457 FALSE,
00458 NULL);
00459 }
00460
00461
if (WorkBuffer !=
NULL) {
00462
ExFreePool(WorkBuffer);
00463 }
00464
ObDereferenceObject(pEvent);
00465 ZwClose(hEvent);
00466
return STATUS_SUCCESS;
00467 }