test: ofsmisc.c Source File

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 }