Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ofsmisc.c

Go to the documentation of this file.
00001 //+--------------------------------------------------------------------------- 00002 // 00003 // Microsoft Windows 00004 // Copyright (C) Microsoft Corporation, 1992-1992 00005 // 00006 // File: ofsmisc.c 00007 // 00008 // Contents: Miscellaneous OFS interfaces 00009 // 00010 //--------------------------------------------------------------------------- 00011 00012 #include <nt.h> 00013 #include <ntrtl.h> 00014 #include <nturtl.h> 00015 #include <windows.h> 00016 #include <ole2.h> 00017 00018 00019 //+--------------------------------------------------------------------------- 00020 // Function: SynchronousNtFsControlFile 00021 // 00022 // Synopsis: Call NtFsControlFile and wait if handle is asynchronous 00023 // 00024 // Arguments: [h] -- handle to file/directory/volume 00025 // [pisb] -- pointer to IO_STATUS_BLOCK 00026 // [FsControlCode] -- FsControl code 00027 // [pvIn] -- optional input buffer 00028 // [cbIn] -- input buffer size 00029 // [pvOut] -- optional output buffer 00030 // [cbOut] -- output buffer size 00031 // 00032 // Returns: Status code 00033 //--------------------------------------------------------------------------- 00034 00035 NTSTATUS 00036 SynchronousNtFsControlFile( 00037 IN HANDLE h, 00038 OUT IO_STATUS_BLOCK *pisb, 00039 IN ULONG FsControlCode, 00040 IN VOID *pvIn OPTIONAL, 00041 IN ULONG cbIn, 00042 OUT VOID *pvOut OPTIONAL, 00043 IN ULONG cbOut) 00044 { 00045 NTSTATUS Status; 00046 00047 Status = NtFsControlFile( 00048 h, 00049 NULL, 00050 NULL, 00051 NULL, 00052 pisb, 00053 FsControlCode, 00054 pvIn, 00055 cbIn, 00056 pvOut, 00057 cbOut); 00058 00059 if (Status == STATUS_PENDING) 00060 { 00061 Status = NtWaitForSingleObject(h, TRUE, NULL); 00062 } 00063 return(Status); 00064 } 00065 00066 00067 //+--------------------------------------------------------------------------- 00068 // Function: UsnFsctl, private 00069 // 00070 // Synopsis: Return a USN according to the passed FsControlCode 00071 // 00072 // Arguments: [hf] -- handle to any file/directory in volume 00073 // [pusn] -- pointer to USN to be returned 00074 // [FsControlCode] -- FSCTL_OFS_USN_GENERATE or FSCTL_OFS_USN_GET_CLOSE. 00075 // 00076 // Returns: Status code 00077 //--------------------------------------------------------------------------- 00078 00079 #if defined(_CAIRO_) || DBG 00080 00081 #include "iofs.h" 00082 00083 NTSTATUS 00084 UsnFsctl( 00085 IN HANDLE hf, 00086 OUT USN *pusn, 00087 IN ULONG FsControlCode) 00088 { 00089 NTSTATUS Status; 00090 IO_STATUS_BLOCK isb; 00091 00092 Status = SynchronousNtFsControlFile( 00093 hf, 00094 &isb, 00095 FsControlCode, 00096 NULL, // input buffer 00097 0, // input buffer length 00098 pusn, // output buffer 00099 sizeof(*pusn)); // output buffer length 00100 ASSERT(!NT_SUCCESS(Status) || isb.Information == sizeof(*pusn)); 00101 return(Status); 00102 } 00103 00104 00105 //+--------------------------------------------------------------------------- 00106 // Function: OFSGetCloseUsn, public 00107 // 00108 // Synopsis: Determine the USN associated with the passed handle. 00109 // 00110 // Arguments: [hf] -- handle to any file/directory in volume 00111 // [pusn] -- pointer to USN to be returned 00112 // 00113 // Returns: Status code 00114 //--------------------------------------------------------------------------- 00115 00116 NTSTATUS NTSYSAPI NTAPI 00117 OFSGetCloseUsn( 00118 IN HANDLE hf, 00119 OUT USN *pusn) 00120 { 00121 return(UsnFsctl(hf, pusn, FSCTL_OFS_USN_GET_CLOSE)); 00122 } 00123 00124 00125 //+--------------------------------------------------------------------------- 00126 // Function: RtlGenerateUsn, public 00127 // 00128 // Synopsis: Generate and return the next USN associated with a volume. 00129 // 00130 // Arguments: [hf] -- handle to any file/directory in volume 00131 // [pusn] -- pointer to USN to be returned 00132 // 00133 // Returns: Status code 00134 //--------------------------------------------------------------------------- 00135 00136 NTSTATUS NTSYSAPI NTAPI 00137 RtlGenerateUsn( 00138 IN HANDLE hf, 00139 OUT USN *pusn) 00140 { 00141 return(UsnFsctl(hf, pusn, FSCTL_OFS_USN_GENERATE)); 00142 } 00143 00144 00145 //+--------------------------------------------------------------------------- 00146 // Function: OFSGetVersion, public 00147 // 00148 // Synopsis: Determine if the passed handle resides on an OFS volume. 00149 // If pversion != NULL, return the format version number. 00150 // 00151 // Arguments: [hf] -- handle to any file/directory in volume 00152 // [pversion] -- pointer to version (may be NULL) 00153 // 00154 // Returns: Status code 00155 // 00156 //--------------------------------------------------------------------------- 00157 00158 #define QuadAlign(n) (((n) + (sizeof(LONGLONG) - 1)) & ~(sizeof(LONGLONG) - 1)) 00159 00160 #define CSTRUCT(n, type, cchname) \ 00161 (((n) * QuadAlign(sizeof(type) + (cchname) * sizeof(WCHAR)) + \ 00162 sizeof(type) - 1) / \ 00163 sizeof(type)) 00164 00165 NTSTATUS NTSYSAPI NTAPI 00166 OFSGetVersion(HANDLE hf, ULONG *pversion) 00167 { 00168 NTSTATUS Status; 00169 IO_STATUS_BLOCK isb; 00170 00171 FILE_FS_ATTRIBUTE_INFORMATION *pfai; 00172 LARGE_INTEGER faibuf[CSTRUCT(1, FILE_FS_ATTRIBUTE_INFORMATION, 32)]; 00173 00174 pfai = (FILE_FS_ATTRIBUTE_INFORMATION *) faibuf; 00175 00176 Status = NtQueryVolumeInformationFile( 00177 hf, 00178 &isb, 00179 pfai, 00180 sizeof(faibuf), 00181 FileFsAttributeInformation); 00182 if (NT_SUCCESS(Status)) 00183 { 00184 if (pfai->FileSystemNameLength != 3 * sizeof(WCHAR) || 00185 pfai->FileSystemName[0] != L'O' || 00186 pfai->FileSystemName[1] != L'F' || 00187 pfai->FileSystemName[2] != L'S') 00188 { 00189 Status = STATUS_UNRECOGNIZED_VOLUME; 00190 } 00191 else if (pversion != NULL) 00192 { 00193 00194 Status = SynchronousNtFsControlFile( 00195 hf, 00196 &isb, 00197 FSCTL_OFS_VERSION, 00198 NULL, // input buffer 00199 0, // input buffer length 00200 pversion, // output buffer 00201 sizeof(*pversion)); // output buffer length 00202 00203 ASSERT(!NT_SUCCESS(Status) || isb.Information == sizeof(*pversion)); 00204 } 00205 } 00206 return(Status); 00207 } 00208 00209 00210 //+--------------------------------------------------------------------------- 00211 // Function: RtlNameToOleId, public 00212 // 00213 // Synopsis: Translate OLENAMEs to ids 00214 // 00215 // Arguments: [hf] -- handle to *volume* 00216 // [cbNames] -- OLENAMES size 00217 // [pon] -- pointer to OLENAMES 00218 // [pOleId] -- pointer to output array of OleIds 00219 // 00220 // Returns: Status code 00221 // 00222 //--------------------------------------------------------------------------- 00223 00224 NTSTATUS NTSYSAPI NTAPI 00225 RtlNameToOleId( 00226 IN HANDLE hf, // must be volume handle 00227 IN ULONG cbNames, 00228 IN OLENAMES const *pon, 00229 OUT ULONG *pOleId) 00230 { 00231 NTSTATUS Status; 00232 IO_STATUS_BLOCK isb; 00233 00234 Status = SynchronousNtFsControlFile( 00235 hf, 00236 &isb, 00237 FSCTL_OFS_TRANSLATE_OLENAMES, 00238 (VOID *) pon, // input buffer 00239 cbNames, // input buffer length 00240 pOleId, // output buffer 00241 pon->cNames * sizeof(*pOleId)); // output buffer length 00242 return(Status); 00243 } 00244 00245 00246 //+--------------------------------------------------------------------------- 00247 // Function: RtlOleIdToName, public 00248 // 00249 // Synopsis: Translate OLEIDs to names 00250 // 00251 // Arguments: [hf] -- handle to *volume* 00252 // [cOleId] -- count of OleIds in array 00253 // [pOleId] -- pointer to array of OleIds 00254 // [pcbNameBuf] -- pointer to OLENAMES buffer size (updated) 00255 // [pon] -- pointer to OLENAMES buffer 00256 // 00257 // Returns: Status code 00258 // 00259 //--------------------------------------------------------------------------- 00260 00261 NTSTATUS NTSYSAPI NTAPI 00262 RtlOleIdToName( 00263 IN HANDLE hf, // must be volume handle 00264 IN ULONG cOleId, 00265 IN ULONG const *pOleId, 00266 IN OUT ULONG *pcbNameBuf, 00267 OUT OLENAMES *pon) 00268 { 00269 NTSTATUS Status; 00270 IO_STATUS_BLOCK isb; 00271 00272 Status = SynchronousNtFsControlFile( 00273 hf, 00274 &isb, 00275 FSCTL_OFS_TRANSLATE_OLEIDS, 00276 (VOID *) pOleId, // input buffer 00277 cOleId * sizeof(*pOleId), // input buffer length 00278 pon, // output buffer 00279 *pcbNameBuf); // output buffer length 00280 *pcbNameBuf = isb.Information; 00281 return(Status); 00282 } 00283 00284 00285 //+--------------------------------------------------------------------------- 00286 // Function: RtlQueryQuota, public 00287 // 00288 // Synopsis: Query Quota information for specific users 00289 // 00290 // Arguments: [hf] -- handle to *volume* 00291 // [pcb] -- length of buffer on input and output 00292 // [pfqi] -- pointer quota information to be filled in 00293 // 00294 // Returns: Status code 00295 // 00296 //--------------------------------------------------------------------------- 00297 00298 NTSTATUS NTSYSAPI NTAPI 00299 RtlQueryQuota( 00300 IN HANDLE hf, // must be volume handle 00301 IN OUT ULONG *pcb, 00302 IN OUT FILE_QUOTA_INFORMATION *pfqi) 00303 { 00304 NTSTATUS Status; 00305 IO_STATUS_BLOCK isb; 00306 00307 Status = SynchronousNtFsControlFile( 00308 hf, 00309 &isb, 00310 FSCTL_OFS_QUERY_QUOTA, 00311 pfqi, // input buffer 00312 *pcb, // input buffer length 00313 pfqi, // output buffer 00314 *pcb); // output buffer length 00315 00316 *pcb = isb.Information; 00317 return(Status); 00318 } 00319 00320 00321 //+--------------------------------------------------------------------------- 00322 // Function: RtlQueryClassId, public 00323 // 00324 // Synopsis: Fetch the ClassId for an open handle 00325 // 00326 // Arguments: [hf] -- handle to file 00327 // [pclsid] -- pointer to ClassId buffer 00328 // 00329 // Returns: Status code 00330 //--------------------------------------------------------------------------- 00331 00332 FILE_OBJECTID_INFORMATION foiiZero; 00333 00334 NTSTATUS NTSYSAPI NTAPI 00335 RtlQueryClassId( 00336 IN HANDLE hf, 00337 OUT GUID *pclsid) 00338 { 00339 NTSTATUS Status; 00340 IO_STATUS_BLOCK isb; 00341 FILE_OLE_INFORMATION foi; 00342 00343 ASSERT(sizeof(GUID) == sizeof(foiiZero.ObjectId.Lineage)); 00344 Status = NtQueryInformationFile( 00345 hf, 00346 &isb, 00347 &foi, 00348 sizeof(foi), 00349 FileOleInformation); 00350 if (NT_SUCCESS(Status)) 00351 { 00352 if (RtlCompareMemory( 00353 &foiiZero.ObjectId.Lineage, 00354 &foi.OleClassIdInformation.ClassId, 00355 sizeof(foiiZero.ObjectId.Lineage)) == 00356 sizeof(foiiZero.ObjectId.Lineage)) 00357 { 00358 Status = STATUS_NOT_FOUND; 00359 } 00360 else 00361 { 00362 *pclsid = foi.OleClassIdInformation.ClassId; 00363 } 00364 } 00365 return(Status); 00366 } 00367 00368 00369 //+--------------------------------------------------------------------------- 00370 // Function: RtlSetClassId, public 00371 // 00372 // Synopsis: Set the ClassId for an open handle 00373 // 00374 // Arguments: [hf] -- handle to file 00375 // [pclsid] -- pointer to ClassId -- NULL means delete 00376 // 00377 // Returns: Status code 00378 //--------------------------------------------------------------------------- 00379 00380 NTSTATUS NTSYSAPI NTAPI 00381 RtlSetClassId( 00382 IN HANDLE hf, 00383 OPTIONAL IN GUID const *pclsid) 00384 { 00385 NTSTATUS Status; 00386 IO_STATUS_BLOCK isb; 00387 00388 ASSERT(sizeof(foiiZero.ObjectId.Lineage) == sizeof(*pclsid)); 00389 Status = NtSetInformationFile( 00390 hf, 00391 &isb, 00392 pclsid == NULL? &foiiZero.ObjectId.Lineage : (VOID *) pclsid, 00393 sizeof(foiiZero.ObjectId.Lineage), 00394 FileOleClassIdInformation); 00395 return(Status); 00396 } 00397 00398 00399 //+--------------------------------------------------------------------------- 00400 // Function: RtlQueryObjectId, public 00401 // 00402 // Synopsis: Fetch the ObjectId for an open handle 00403 // 00404 // Arguments: [hf] -- handle to file 00405 // [poid] -- pointer to ObjectId buffer 00406 // 00407 // Returns: Status code 00408 //--------------------------------------------------------------------------- 00409 00410 NTSTATUS NTSYSAPI NTAPI 00411 RtlQueryObjectId( 00412 IN HANDLE hf, 00413 OUT OBJECTID *poid) 00414 { 00415 NTSTATUS Status; 00416 IO_STATUS_BLOCK isb; 00417 FILE_OLE_INFORMATION foi; 00418 00419 Status = NtQueryInformationFile( 00420 hf, 00421 &isb, 00422 &foi, 00423 sizeof(foi), 00424 FileOleInformation); 00425 if (NT_SUCCESS(Status)) 00426 { 00427 if (RtlCompareMemory( 00428 &foiiZero.ObjectId, 00429 &foi.ObjectIdInformation.ObjectId, 00430 sizeof(foiiZero.ObjectId)) == sizeof(foiiZero.ObjectId)) 00431 { 00432 Status = STATUS_NOT_FOUND; 00433 } 00434 else 00435 { 00436 *poid = foi.ObjectIdInformation.ObjectId; 00437 } 00438 } 00439 return(Status); 00440 } 00441 00442 00443 //+--------------------------------------------------------------------------- 00444 // Function: RtlSetObjectId, public 00445 // 00446 // Synopsis: Set the ObjectId for an open handle 00447 // 00448 // Arguments: [hf] -- handle to file 00449 // [poid] -- pointer to ObjectId -- NULL means delete 00450 // 00451 // Returns: Status code 00452 //--------------------------------------------------------------------------- 00453 00454 NTSTATUS NTSYSAPI NTAPI 00455 RtlSetObjectId( 00456 IN HANDLE hf, 00457 OPTIONAL IN OBJECTID const *poid) 00458 { 00459 NTSTATUS Status; 00460 IO_STATUS_BLOCK isb; 00461 00462 ASSERT(sizeof(foiiZero) == sizeof(*poid)); 00463 Status = NtSetInformationFile( 00464 hf, 00465 &isb, 00466 poid == NULL? &foiiZero : (VOID *) poid, 00467 sizeof(foiiZero), 00468 FileObjectIdInformation); 00469 return(Status); 00470 } 00471 00472 00473 //+--------------------------------------------------------------------------- 00474 // Function: RtlSetTunnelMode, public 00475 // 00476 // Synopsis: Set the ObjectId tunnel mode for an OFS volume. 00477 // 00478 // Arguments: [hVolume] -- handle to volume 00479 // [ulFlags] -- Bits to set 00480 // [ulMask] -- Mask of bits to change 00481 // [pulOld] -- pointer to store Old flags 00482 // 00483 // Returns: Status code 00484 //--------------------------------------------------------------------------- 00485 00486 NTSTATUS 00487 RtlSetTunnelMode( 00488 IN HANDLE hVolume, 00489 IN ULONG ulFlags, 00490 IN ULONG ulMask, 00491 OUT ULONG *pulOld) 00492 { 00493 TUNNELMODE tm; 00494 TUNNELMODEOUT tmo; 00495 NTSTATUS Status; 00496 IO_STATUS_BLOCK isb; 00497 00498 tm.ulFlags = ulFlags; 00499 tm.ulMask = ulMask; 00500 00501 Status = SynchronousNtFsControlFile( 00502 hVolume, // Handle 00503 &isb, // I/O Status block 00504 FSCTL_OFS_TUNNEL_MODE, // Control code 00505 &tm, // Input buffer 00506 sizeof(tm), // Input length 00507 &tmo, // Output buffer 00508 sizeof(tmo)); // Output length 00509 00510 *pulOld = tmo.ulFlags; 00511 return(Status); 00512 } 00513 00514 00515 //+--------------------------------------------------------------------------- 00516 // Function: RtlSearchVolume, public 00517 // 00518 // Synopsis: Search an OFS volume for files with passed ObjectId 00519 // 00520 // Arguments: [hAncestor] -- handle to file 00521 // [poid] -- pointer to ObjectId 00522 // [cLineage] -- Lineage count/flags 00523 // [fContinue] -- TRUE if should continue 00524 // [usBufLen] -- output buffer length 00525 // [pResults] -- output buffer 00526 // 00527 // Returns: Status code 00528 //--------------------------------------------------------------------------- 00529 00530 NTSTATUS NTSYSAPI NTAPI 00531 RtlSearchVolume( 00532 IN HANDLE hAncestor, 00533 IN OBJECTID const *poid, 00534 IN USHORT cLineage, 00535 IN BOOLEAN fContinue, 00536 IN ULONG usBufLen, 00537 OUT FINDOBJECTOUT *pfoo) 00538 { 00539 NTSTATUS Status; 00540 IO_STATUS_BLOCK isb; 00541 00542 ((FINDOBJECT *) pfoo)->oid = *poid; 00543 ((FINDOBJECT *) pfoo)->cLineage = cLineage; 00544 ((FINDOBJECT *) pfoo)->ulFlags = fContinue? FO_CONTINUE_ENUM : 0; 00545 00546 Status = SynchronousNtFsControlFile( 00547 hAncestor, // Handle 00548 &isb, // I/O Status block 00549 FSCTL_OFS_FINDOBJECT, // Control code 00550 pfoo, // Input buffer 00551 sizeof(FINDOBJECT), // Input length 00552 pfoo, // Output buffer 00553 usBufLen); // Output length 00554 return(Status); 00555 } 00556 00557 00558 //+--------------------------------------------------------------------------- 00559 // Function: RtlGenerateRelatedObjectId, public 00560 // 00561 // Synopsis: Generate an object id which is related to the one passed in. 00562 // 00563 // Arguments: [poidOld] -- pointer to original ObjectId 00564 // [poidNew] -- pointer to buffer for new ObjectId 00565 // 00566 // Returns: Status code 00567 //--------------------------------------------------------------------------- 00568 00569 VOID NTSYSAPI NTAPI 00570 RtlGenerateRelatedObjectId( 00571 IN OBJECTID const *poidOld, 00572 OUT OBJECTID *poidNew) 00573 { 00574 poidNew->Lineage = poidOld->Lineage; 00575 do 00576 { 00577 poidNew->Uniquifier = rand(); 00578 } while (poidNew->Uniquifier == poidOld->Uniquifier); 00579 } 00580 00581 00582 //+--------------------------------------------------------------------------- 00583 // Function: RtlSetReplicationState, public 00584 // 00585 // Synopsis: Generate an object id which is related to the one passed in. 00586 // 00587 // Arguments: [hf] -- handle 00588 // 00589 // Returns: Status code 00590 //--------------------------------------------------------------------------- 00591 00592 NTSTATUS NTSYSAPI NTAPI 00593 RtlSetReplicationState( 00594 IN HANDLE hf) 00595 { 00596 IO_STATUS_BLOCK isb; 00597 00598 return(SynchronousNtFsControlFile( 00599 hf, // Handle 00600 &isb, // I/O Status block 00601 FSCTL_SET_REPLICATION_STATE,// Control code 00602 NULL, // Input buffer 00603 0, // Input length 00604 NULL, // Output buffer 00605 0)); // Output length 00606 } 00607 00608 #endif // _CAIRO_ 00609 00610 //+--------------------------------------------------------------------------- 00611 // Function: _purecall, private 00612 // 00613 // Synopsis: C++ stub 00614 // 00615 // Arguments: NONE 00616 // 00617 // Returns: NONE 00618 // 00619 //--------------------------------------------------------------------------- 00620 00621 VOID __cdecl 00622 _purecall(VOID) 00623 { 00624 ASSERTMSG("_purecall() was called", FALSE); 00625 RtlRaiseStatus(STATUS_NOT_IMPLEMENTED); 00626 }

Generated on Sat May 15 19:41:06 2004 for test by doxygen 1.3.7