volumeid.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 20k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * volumeid.c - Volume ID ADT module.
  3.  */
  4. /* Headers
  5.  **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. #include "volumeid.h"
  9. /* Constants
  10.  ************/
  11. /* local root path constants */
  12. #define MAX_LOCAL_DRIVES            (TEXT('z') - TEXT('a') + 1)
  13. /* Macros
  14.  *********/
  15. /* macros for accessing IVOLUMEID data */
  16. #define IVOLID_Volume_Label_PtrA(pivolid) 
  17.    ((LPSTR)(((PBYTE)(pivolid)) + (pivolid)->ucbVolumeLabelOffset))
  18. #ifdef UNICODE
  19. #define IVOLID_Volume_Label_PtrW(pivolid) 
  20.    ((LPTSTR)(((PBYTE)(pivolid)) + (pivolid)->ucbVolumeLabelOffsetW))
  21. #endif
  22. #ifdef UNICODE
  23. #define IVOLID_Volume_Label_Ptr(pivolid)   IVOLID_Volume_Label_PtrW(pivolid)
  24. #else
  25. #define IVOLID_Volume_Label_Ptr(pivolid)   IVOLID_Volume_Label_PtrA(pivolid)
  26. #endif
  27. /* Types
  28.  ********/
  29. /*
  30.    @doc INTERNAL
  31.    @struct IVOLUMEID | Internal definition of relocatable volume ID structure.
  32.    An <t ILINKINFO> structure may contain an IVOLUMEID structure.  An IVOLUMEID
  33.    structure consists of a header described as below, followed by
  34.    variable-length data.
  35. */
  36. typedef struct _ivolumeidA
  37. {
  38.    /*
  39.       @field UINT | ucbSize | Length of IVOLUMEID structure in bytes, including
  40.       ucbSize field.
  41.    */
  42.    UINT ucbSize;
  43.    /*
  44.       @field UINT | uDriveType | The volume's host drive type, as returned by
  45.       GetDriveType()
  46.    */
  47.    UINT uDriveType;
  48.    /* @field DWORD | dwSerialNumber | The volume's serial number. */
  49.    DWORD dwSerialNumber;
  50.    /*
  51.       @field UINT | ucbVolumeLabelOffset | Offset in bytes of volume label
  52.       string from base of structure.
  53.    */
  54.    UINT ucbVolumeLabelOffset;
  55. }
  56. IVOLUMEIDA;
  57. DECLARE_STANDARD_TYPES(IVOLUMEIDA);
  58. #ifdef UNICODE
  59. typedef struct _ivolumeidW
  60. {
  61.    /*
  62.       @field UINT | ucbSize | Length of IVOLUMEID structure in bytes, including
  63.       ucbSize field.
  64.    */
  65.    UINT ucbSize;
  66.    /*
  67.       @field UINT | uDriveType | The volume's host drive type, as returned by
  68.       GetDriveType()
  69.    */
  70.    UINT uDriveType;
  71.    /* @field DWORD | dwSerialNumber | The volume's serial number. */
  72.    DWORD dwSerialNumber;
  73.    /*
  74.       @field UINT | ucbVolumeLabelOffset | Offset in bytes of volume label
  75.       string from base of structure.
  76.    */
  77.    UINT ucbVolumeLabelOffset;
  78.    /*
  79.       This member is for storing the unicode version of the string
  80.    */
  81.    UINT ucbVolumeLabelOffsetW;
  82. }
  83. IVOLUMEIDW;
  84. DECLARE_STANDARD_TYPES(IVOLUMEIDW);
  85. #endif
  86. #ifdef UNICODE
  87. #define IVOLUMEID   IVOLUMEIDW
  88. #define PIVOLUMEID  PIVOLUMEIDW
  89. #define CIVOLUMEID  CIVOLUMEIDW
  90. #define PCIVOLUMEID PCIVOLUMEIDW
  91. #else
  92. #define IVOLUMEID   IVOLUMEIDA
  93. #define PIVOLUMEID  PIVOLUMEIDA
  94. #define CIVOLUMEID  CIVOLUMEIDA
  95. #define PCIVOLUMEID PCIVOLUMEIDA
  96. #endif
  97. /***************************** Private Functions *****************************/
  98. /* Module Prototypes
  99.  ********************/
  100. PRIVATE_CODE BOOL UnifyIVolumeIDInfo(UINT, DWORD, LPCTSTR, PIVOLUMEID *, PUINT);
  101. PRIVATE_CODE BOOL IsPathOnVolume(LPCTSTR, PCIVOLUMEID, PBOOL);
  102. PRIVATE_CODE COMPARISONRESULT CompareUINTs(UINT, UINT);
  103. #if defined(DEBUG) || defined (VSTF)
  104. PRIVATE_CODE BOOL IsValidPCIVOLUMEID(PCIVOLUMEID);
  105. #endif
  106. /*
  107. ** UnifyIVolumeIDInfo()
  108. **
  109. **
  110. **
  111. ** Arguments:
  112. **
  113. ** Returns:
  114. **
  115. ** Side Effects:  none
  116. */
  117. PRIVATE_CODE BOOL UnifyIVolumeIDInfo(UINT uDriveType, DWORD dwSerialNumber,
  118.                                 LPCTSTR pcszVolumeLabel, PIVOLUMEID *ppivolid,
  119.                                 PUINT pucbIVolumeIDLen)
  120. {
  121.    BOOL bResult;
  122. #ifdef UNICODE
  123.    CHAR szAnsiVolumeLabel[MAX_PATH];
  124.    BOOL bUnicode;
  125.    UINT cchVolumeLabel;
  126.    UINT cchChars;
  127. #endif
  128.    /* dwSerialNumber may be any value. */
  129.    ASSERT(IsValidDriveType(uDriveType));
  130.    ASSERT(IS_VALID_STRING_PTR(pcszVolumeLabel, CSTR));
  131.    ASSERT(IS_VALID_WRITE_PTR(ppivolid, PIVOLUMEID));
  132.    ASSERT(IS_VALID_WRITE_PTR(pucbIVolumeIDLen, UINT));
  133.    /* Assume we won't overflow *pucbIVolumeIDLen here. */
  134. #ifdef UNICODE
  135.    /* Determine whether we need a full fledged UNICODE volume ID */
  136.    bUnicode = FALSE;
  137.    cchVolumeLabel = WideCharToMultiByte(CP_ACP, 0,
  138.                                         pcszVolumeLabel, -1,
  139.                                         szAnsiVolumeLabel, MAX_PATH,
  140.                                         0, 0);
  141.    if ( cchVolumeLabel == 0 )
  142.    {
  143.       bUnicode = TRUE;
  144.    }
  145.    else
  146.    {
  147.       WCHAR szWideVolumeLabel[MAX_PATH];
  148.       cchChars = MultiByteToWideChar(CP_ACP, 0,
  149.                                      szAnsiVolumeLabel, -1,
  150.                                      szWideVolumeLabel, MAX_PATH);
  151.       if ( cchChars == 0 || lstrcmp(pcszVolumeLabel,szWideVolumeLabel) != 0 )
  152.       {
  153.          bUnicode = TRUE;
  154.       }
  155.    }
  156.    if ( bUnicode )
  157.    {
  158.       UINT ucbDataSize;
  159.       /* (+ 1) for null terminator. */
  160.       ucbDataSize = SIZEOF(IVOLUMEIDW) + cchVolumeLabel;
  161.       ucbDataSize = ALIGN_WORD_CNT(ucbDataSize);
  162.       ucbDataSize += (lstrlen(pcszVolumeLabel) + 1) * SIZEOF(TCHAR);
  163.       *pucbIVolumeIDLen = ucbDataSize;
  164.    }
  165.    else
  166.    {
  167.       /* (+ 1) for null terminator. */
  168.       *pucbIVolumeIDLen = SIZEOF(IVOLUMEIDA) +
  169.                           cchVolumeLabel;
  170.    }
  171. #else
  172.    /* (+ 1) for null terminator. */
  173.    *pucbIVolumeIDLen = SIZEOF(**ppivolid) +
  174.                        (lstrlen(pcszVolumeLabel) + 1) * SIZEOF(TCHAR);
  175. #endif
  176.    bResult = AllocateMemory(*pucbIVolumeIDLen, ppivolid);
  177.    if (bResult)
  178.    {
  179.       (*ppivolid)->ucbSize = *pucbIVolumeIDLen;
  180.       (*ppivolid)->uDriveType = uDriveType;
  181.       (*ppivolid)->dwSerialNumber = dwSerialNumber;
  182.       /* Append volume label. */
  183. #ifdef UNICODE
  184.       if ( bUnicode )
  185.       {
  186.           (*ppivolid)->ucbVolumeLabelOffset = SIZEOF(IVOLUMEIDW);
  187.           (*ppivolid)->ucbVolumeLabelOffsetW = ALIGN_WORD_CNT(
  188.                                          SIZEOF(IVOLUMEIDW)+cchVolumeLabel);
  189.           lstrcpy(IVOLID_Volume_Label_PtrW(*ppivolid), pcszVolumeLabel);
  190.       }
  191.       else
  192.       {
  193.           (*ppivolid)->ucbVolumeLabelOffset = SIZEOF(IVOLUMEIDA);
  194.       }
  195.       lstrcpyA(IVOLID_Volume_Label_PtrA(*ppivolid), szAnsiVolumeLabel);
  196. #else
  197.       lstrcpy(IVOLID_Volume_Label_Ptr(*ppivolid), pcszVolumeLabel);
  198. #endif
  199.    }
  200.    ASSERT(! bResult ||
  201.           (IS_VALID_STRUCT_PTR(*ppivolid, CIVOLUMEID) &&
  202.            EVAL(*pucbIVolumeIDLen == GetVolumeIDLen((PCVOLUMEID)*ppivolid))));
  203.    return(bResult);
  204. }
  205. /*
  206. ** IsPathOnVolume()
  207. **
  208. **
  209. **
  210. ** Arguments:
  211. **
  212. ** Returns:
  213. **
  214. ** Side Effects:  none
  215. */
  216. PRIVATE_CODE BOOL IsPathOnVolume(LPCTSTR pcszDrivePath, PCIVOLUMEID pcivolid,
  217.                                  PBOOL pbOnVolume)
  218. {
  219.    BOOL bResult;
  220.    PVOLUMEID pvolid;
  221.    UINT ucbVolumeIDLen;
  222.    ASSERT(IsDrivePath(pcszDrivePath));
  223.    ASSERT(IS_VALID_STRUCT_PTR(pcivolid, CIVOLUMEID));
  224.    ASSERT(IS_VALID_WRITE_PTR(pcivolid, CIVOLUMEID));
  225.    bResult = CreateVolumeID(pcszDrivePath, &pvolid, &ucbVolumeIDLen);
  226.    if (bResult)
  227.    {
  228.       *pbOnVolume = (CompareVolumeIDs(pvolid, (PCVOLUMEID)pcivolid)
  229.                      == CR_EQUAL);
  230.       DestroyVolumeID(pvolid);
  231.    }
  232.    return(bResult);
  233. }
  234. /*
  235. ** CompareUINTs()
  236. **
  237. **
  238. **
  239. ** Arguments:
  240. **
  241. ** Returns:
  242. **
  243. ** Side Effects:  none
  244. */
  245. PRIVATE_CODE COMPARISONRESULT CompareUINTs(UINT uFirst, UINT uSecond)
  246. {
  247.    COMPARISONRESULT cr;
  248.    /* Any UINTs are valid input. */
  249.    if (uFirst < uSecond)
  250.       cr = CR_FIRST_SMALLER;
  251.    else if (uFirst > uSecond)
  252.       cr = CR_FIRST_LARGER;
  253.    else
  254.       cr = CR_EQUAL;
  255.    ASSERT(IsValidCOMPARISONRESULT(cr));
  256.    return(cr);
  257. }
  258. #if defined(DEBUG) || defined (VSTF)
  259. /*
  260. ** IsValidPCIVOLUMEID()
  261. **
  262. **
  263. **
  264. ** Arguments:
  265. **
  266. ** Returns:
  267. **
  268. ** Side Effects:  none
  269. */
  270. PRIVATE_CODE BOOL IsValidPCIVOLUMEID(PCIVOLUMEID pcivolid)
  271. {
  272.    /* dwSerialNumber may be any value. */
  273.    return(IS_VALID_READ_PTR(pcivolid, CIVOLUMEID) &&
  274.           IS_VALID_READ_BUFFER_PTR(pcivolid, CIVOLUMEID, pcivolid->ucbSize) &&
  275.           EVAL(IsValidDriveType(pcivolid->uDriveType)) &&
  276.           EVAL(IsContained(pcivolid, pcivolid->ucbSize,
  277.                            IVOLID_Volume_Label_Ptr(pcivolid),
  278.                            lstrlen(IVOLID_Volume_Label_Ptr(pcivolid))*SIZEOF(TCHAR))));
  279. }
  280. #endif
  281. /****************************** Public Functions *****************************/
  282. /*
  283. ** CreateVolumeID()
  284. **
  285. **
  286. **
  287. ** Arguments:
  288. **
  289. ** Returns:
  290. **
  291. ** Side Effects:  none
  292. */
  293. PUBLIC_CODE BOOL CreateVolumeID(LPCTSTR pcszDrivePath, PVOLUMEID *ppvolid,
  294.                                 PUINT pucbVolumeIDLen)
  295. {
  296.    BOOL bResult;
  297.    /* "C:" + null terminator. */
  298.    TCHAR rgchRootPath[3 + 1];
  299.    TCHAR rgchVolumeLabel[MAX_PATH_LEN];
  300.    DWORD dwSerialNumber;
  301.    ASSERT(IsDrivePath(pcszDrivePath));
  302.    ASSERT(IS_VALID_WRITE_PTR(ppvolid, PVOLUMEID));
  303.    ASSERT(IS_VALID_WRITE_PTR(pucbVolumeIDLen, UINT));
  304.    /* Get volume's label and serial number. */
  305.    MyLStrCpyN(rgchRootPath, pcszDrivePath, ARRAYSIZE(rgchRootPath));
  306.    bResult = GetVolumeInformation(rgchRootPath, rgchVolumeLabel,
  307.                                   ARRAYSIZE(rgchVolumeLabel), &dwSerialNumber,
  308.                                   NULL, NULL, NULL, 0);
  309.    if (bResult)
  310.       /* Wrap them up. */
  311.       bResult = UnifyIVolumeIDInfo(GetDriveType(rgchRootPath), dwSerialNumber,
  312.                                    rgchVolumeLabel, (PIVOLUMEID *)ppvolid,
  313.                                    pucbVolumeIDLen);
  314.    ASSERT(! bResult ||
  315.           IS_VALID_STRUCT_PTR((PCIVOLUMEID)*ppvolid, CIVOLUMEID));
  316.    return(bResult);
  317. }
  318. /*
  319. ** DestroyVolumeID()
  320. **
  321. **
  322. **
  323. ** Arguments:
  324. **
  325. ** Returns:
  326. **
  327. ** Side Effects:  none
  328. */
  329. PUBLIC_CODE void DestroyVolumeID(PVOLUMEID pvolid)
  330. {
  331.    ASSERT(IS_VALID_STRUCT_PTR(pvolid, CVOLUMEID));
  332.    FreeMemory(pvolid);
  333.    return;
  334. }
  335. /*
  336. ** CompareVolumeIDs()
  337. **
  338. **
  339. **
  340. ** Arguments:
  341. **
  342. ** Returns:
  343. **
  344. ** Side Effects:  none
  345. **
  346. ** Volume ID data is compared in the following order:
  347. **    1) drive type
  348. **    2) volume serial number
  349. **
  350. ** N.b., volume labels are ignored.
  351. */
  352. PUBLIC_CODE COMPARISONRESULT CompareVolumeIDs(PCVOLUMEID pcvolidFirst,
  353.                                          PCVOLUMEID pcvolidSecond)
  354. {
  355.    COMPARISONRESULT cr;
  356.    ASSERT(IS_VALID_STRUCT_PTR(pcvolidFirst, CVOLUMEID));
  357.    ASSERT(IS_VALID_STRUCT_PTR(pcvolidSecond, CVOLUMEID));
  358.    /* Compare VOLUMEIDs piece by piece. */
  359.    cr = CompareUINTs(((PCIVOLUMEID)pcvolidFirst)->uDriveType,
  360.                      ((PCIVOLUMEID)pcvolidSecond)->uDriveType);
  361.    if (cr == CR_EQUAL)
  362.       cr = CompareDWORDs(((PCIVOLUMEID)pcvolidFirst)->dwSerialNumber,
  363.                          ((PCIVOLUMEID)pcvolidSecond)->dwSerialNumber);
  364.    return(cr);
  365. }
  366. /*
  367. ** SearchForLocalPath()
  368. **
  369. **
  370. **
  371. ** Arguments:
  372. **
  373. ** Returns:
  374. **
  375. ** Side Effects:  none
  376. */
  377. PUBLIC_CODE BOOL SearchForLocalPath(PCVOLUMEID pcvolid, LPCTSTR pcszFullPath,
  378.                                DWORD dwInFlags, LPTSTR pszFoundPathBuf)
  379. {
  380.    BOOL bResult;
  381.    BOOL bAvailable;
  382. #if defined(DEBUG) && defined(UNICODE)
  383.    WCHAR szWideVolumeLabel[MAX_PATH];
  384.    LPWSTR pszWideVolumeLabel;
  385. #endif
  386.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  387.    ASSERT(IsFullPath(pcszFullPath));
  388.    ASSERT(FLAGS_ARE_VALID(dwInFlags, ALL_SFLP_IFLAGS));
  389.    ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszFoundPathBuf, STR, MAX_PATH_LEN));
  390. #if defined(DEBUG) && defined(UNICODE)
  391.    if (((PCIVOLUMEID)pcvolid)->ucbVolumeLabelOffset == SIZEOF(IVOLUMEIDA))
  392.    {
  393.       pszWideVolumeLabel = szWideVolumeLabel;
  394.       MultiByteToWideChar(CP_ACP, 0,
  395.                           IVOLID_Volume_Label_PtrA((PCIVOLUMEID)pcvolid), -1,
  396.                           szWideVolumeLabel, MAX_PATH);
  397.    }
  398.    else
  399.    {
  400.       pszWideVolumeLabel = IVOLID_Volume_Label_Ptr((PCIVOLUMEID)pcvolid);
  401.    }
  402. #endif
  403.    /* Were we given a local path to check first? */
  404.    if (IsLocalDrivePath(pcszFullPath))
  405.       /* Yes.  Check it. */
  406.       bResult = IsPathOnVolume(pcszFullPath, (PCIVOLUMEID)pcvolid,
  407.                                &bAvailable);
  408.    else
  409.    {
  410.       /* No. */
  411.       bAvailable = FALSE;
  412.       bResult = TRUE;
  413.    }
  414.    if (bResult)
  415.    {
  416.       /* Did we find the volume? */
  417.       if (bAvailable)
  418.       {
  419.          /* Yes. */
  420.          ASSERT(lstrlen(pcszFullPath) < MAX_PATH_LEN);
  421.          lstrcpy(pszFoundPathBuf, pcszFullPath);
  422.       }
  423.       else
  424.       {
  425.          /*
  426.           * No.  Should we search other matching local devices for the volume?
  427.           */
  428.          if (IS_FLAG_SET(dwInFlags, SFLP_IFL_LOCAL_SEARCH))
  429.          {
  430.             TCHAR chOriginalDrive;
  431.             UINT uDrive;
  432.             DWORD dwLogicalDrives;
  433.             /* Yes. */
  434. #ifdef UNICODE
  435.             WARNING_OUT((TEXT("SearchForLocalPath(): Searching for local volume "%s", as requested."),
  436.                          pszWideVolumeLabel));
  437. #else
  438.             WARNING_OUT((TEXT("SearchForLocalPath(): Searching for local volume "%s", as requested."),
  439.                          IVOLID_Volume_Label_Ptr((PCIVOLUMEID)pcvolid)));
  440. #endif
  441.             ASSERT(IsCharAlpha(*pcszFullPath));
  442.             chOriginalDrive = *pcszFullPath;
  443.             ASSERT(lstrlen(pcszFullPath) < MAX_PATH_LEN);
  444.             lstrcpy(pszFoundPathBuf, pcszFullPath);
  445.             /* Get bit mask of local logical drives. */
  446.             dwLogicalDrives = GetLogicalDrives();
  447.             for (uDrive = 0; uDrive < MAX_LOCAL_DRIVES; uDrive++)
  448.             {
  449.                if (IS_FLAG_SET(dwLogicalDrives, (1 << uDrive)))
  450.                {
  451.                   TCHAR chDrive;
  452.                   chDrive = (TCHAR)(TEXT('A') + uDrive);
  453.                   ASSERT(IsCharAlpha(chDrive));
  454.                   if (chDrive != chOriginalDrive)
  455.                   {
  456.                      TCHAR rgchLocalRootPath[DRIVE_ROOT_PATH_LEN];
  457.                      lstrcpy(rgchLocalRootPath, TEXT("A:\"));
  458.                      rgchLocalRootPath[0] = chDrive;
  459.                      /*
  460.                       * Does this drive's type match the target volume's drive
  461.                       * type?
  462.                       */
  463.                      if (GetDriveType(rgchLocalRootPath) == ((PCIVOLUMEID)pcvolid)->uDriveType)
  464.                      {
  465.                         /* Yes.  Check the volume. */
  466.                         TRACE_OUT((TEXT("SearchForLocalPath(): Checking local root path %s."),
  467.                                    rgchLocalRootPath));
  468.                         bResult = IsPathOnVolume(rgchLocalRootPath,
  469.                                                  (PCIVOLUMEID)pcvolid,
  470.                                                  &bAvailable);
  471.                         if (bResult)
  472.                         {
  473.                            if (bAvailable)
  474.                            {
  475.                               ASSERT(lstrlen(pcszFullPath) < MAX_PATH_LEN);
  476.                               lstrcpy(pszFoundPathBuf, pcszFullPath);
  477.                               ASSERT(IsCharAlpha(*pszFoundPathBuf));
  478.                               *pszFoundPathBuf = chDrive;
  479.                               TRACE_OUT((TEXT("SearchForLocalPath(): Found matching volume on local path %s."),
  480.                                          pszFoundPathBuf));
  481.                               break;
  482.                            }
  483.                         }
  484.                         else
  485.                            break;
  486.                      }
  487.                   }
  488.                }
  489.             }
  490.          }
  491.          else
  492.             /* No. */
  493. #ifdef UNICODE
  494.             WARNING_OUT((TEXT("SearchForLocalPath(): Not searching for local volume "%s", as requested."),
  495.                          pszWideVolumeLabel));
  496. #else
  497.             WARNING_OUT((TEXT("SearchForLocalPath(): Not searching for local volume "%s", as requested."),
  498.                          IVOLID_Volume_Label_Ptr((PCIVOLUMEID)pcvolid)));
  499. #endif
  500.       }
  501.    }
  502.    ASSERT(! bResult ||
  503.           ! bAvailable ||
  504.           IsLocalDrivePath(pszFoundPathBuf));
  505.    return(bResult && bAvailable);
  506. }
  507. /*
  508. ** GetVolumeIDLen()
  509. **
  510. **
  511. **
  512. ** Arguments:
  513. **
  514. ** Returns:
  515. **
  516. ** Side Effects:  none
  517. */
  518. PUBLIC_CODE UINT GetVolumeIDLen(PCVOLUMEID pcvolid)
  519. {
  520.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  521.    return(((PCIVOLUMEID)pcvolid)->ucbSize);
  522. }
  523. /*
  524. ** GetVolumeSerialNumber()
  525. **
  526. **
  527. **
  528. ** Arguments:
  529. **
  530. ** Returns:
  531. **
  532. ** Side Effects:  none
  533. */
  534. PUBLIC_CODE BOOL GetVolumeSerialNumber(PCVOLUMEID pcvolid,
  535.                                   PCDWORD *ppcdwSerialNumber)
  536. {
  537.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  538.    ASSERT(IS_VALID_WRITE_PTR(ppcdwSerialNumber, PCDWORD));
  539.    *ppcdwSerialNumber = &(((PCIVOLUMEID)pcvolid)->dwSerialNumber);
  540.    ASSERT(IS_VALID_READ_PTR(*ppcdwSerialNumber, CDWORD));
  541.    return(TRUE);
  542. }
  543. /*
  544. ** GetVolumeDriveType()
  545. **
  546. **
  547. **
  548. ** Arguments:
  549. **
  550. ** Returns:
  551. **
  552. ** Side Effects:  none
  553. */
  554. PUBLIC_CODE BOOL GetVolumeDriveType(PCVOLUMEID pcvolid, PCUINT *ppcuDriveType)
  555. {
  556.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  557.    ASSERT(IS_VALID_WRITE_PTR(ppcuDriveType, PCUINT));
  558.    *ppcuDriveType = &(((PCIVOLUMEID)pcvolid)->uDriveType);
  559.    ASSERT(IS_VALID_READ_PTR(*ppcuDriveType, CUINT));
  560.    return(TRUE);
  561. }
  562. /*
  563. ** GetVolumeLabel()
  564. **
  565. **
  566. **
  567. ** Arguments:
  568. **
  569. ** Returns:
  570. **
  571. ** Side Effects:  none
  572. */
  573. PUBLIC_CODE BOOL GetVolumeLabel(PCVOLUMEID pcvolid, LPCSTR *ppcszVolumeLabel)
  574. {
  575.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  576.    ASSERT(IS_VALID_WRITE_PTR(ppcszVolumeLabel, LPCTSTR));
  577.    *ppcszVolumeLabel = IVOLID_Volume_Label_PtrA((PCIVOLUMEID)pcvolid);
  578.    ASSERT(IS_VALID_STRING_PTRA(*ppcszVolumeLabel, CSTR));
  579.    return(TRUE);
  580. }
  581. #ifdef UNICODE
  582. /*
  583. ** GetVolumeLabelW()
  584. **
  585. **
  586. **
  587. ** Arguments:
  588. **
  589. ** Returns:
  590. **
  591. ** Side Effects:  none
  592. */
  593. PUBLIC_CODE BOOL GetVolumeLabelW(PCVOLUMEID pcvolid, LPCWSTR *ppcszVolumeLabel)
  594. {
  595.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  596.    ASSERT(IS_VALID_WRITE_PTR(ppcszVolumeLabel, LPCTSTR));
  597.    if (((PCIVOLUMEID)pcvolid)->ucbVolumeLabelOffset == SIZEOF(IVOLUMEIDW))
  598.    {
  599.        *ppcszVolumeLabel = IVOLID_Volume_Label_PtrW((PCIVOLUMEID)pcvolid);
  600.        ASSERT(IS_VALID_STRING_PTR(*ppcszVolumeLabel, CSTR));
  601.    }
  602.    else
  603.    {
  604.        *ppcszVolumeLabel = NULL;
  605.    }
  606.    return(TRUE);
  607. }
  608. #endif
  609. /*
  610. ** CompareDWORDs()
  611. **
  612. **
  613. **
  614. ** Arguments:
  615. **
  616. ** Returns:
  617. **
  618. ** Side Effects:  none
  619. */
  620. PUBLIC_CODE COMPARISONRESULT CompareDWORDs(DWORD dwFirst, DWORD dwSecond)
  621. {
  622.    COMPARISONRESULT cr;
  623.    /* Any DWORDs are valid input. */
  624.    if (dwFirst < dwSecond)
  625.       cr = CR_FIRST_SMALLER;
  626.    else if (dwFirst > dwSecond)
  627.       cr = CR_FIRST_LARGER;
  628.    else
  629.       cr = CR_EQUAL;
  630.    ASSERT(IsValidCOMPARISONRESULT(cr));
  631.    return(cr);
  632. }
  633. #if defined(DEBUG) || defined (VSTF)
  634. /*
  635. ** IsValidPCVOLUMEID()
  636. **
  637. **
  638. **
  639. ** Arguments:
  640. **
  641. ** Returns:
  642. **
  643. ** Side Effects:  none
  644. */
  645. PUBLIC_CODE BOOL IsValidPCVOLUMEID(PCVOLUMEID pcvolid)
  646. {
  647.    return(IS_VALID_STRUCT_PTR((PCIVOLUMEID)pcvolid, CIVOLUMEID));
  648. }
  649. #endif
  650. #ifdef DEBUG
  651. /*
  652. ** DumpVolumeID()
  653. **
  654. **
  655. **
  656. ** Arguments:
  657. **
  658. ** Returns:
  659. **
  660. ** Side Effects:  none
  661. */
  662. PUBLIC_CODE void DumpVolumeID(PCVOLUMEID pcvolid)
  663. {
  664.    ASSERT(IS_VALID_STRUCT_PTR(pcvolid, CVOLUMEID));
  665.    PLAIN_TRACE_OUT((TEXT("%s%s[local volume ID] ucbSize = %#x"),
  666.                     INDENT_STRING,
  667.                     INDENT_STRING,
  668.                     ((PCIVOLUMEID)pcvolid)->ucbSize));
  669.    PLAIN_TRACE_OUT((TEXT("%s%s[local volume ID] drive type %u"),
  670.                     INDENT_STRING,
  671.                     INDENT_STRING,
  672.                     ((PCIVOLUMEID)pcvolid)->uDriveType));
  673.    PLAIN_TRACE_OUT((TEXT("%s%s[local volume ID] serial number %#08lx"),
  674.                     INDENT_STRING,
  675.                     INDENT_STRING,
  676.                     ((PCIVOLUMEID)pcvolid)->dwSerialNumber));
  677.    PLAIN_TRACE_OUT((TEXT("%s%s[local volume ID] label "%s""),
  678.                     INDENT_STRING,
  679.                     INDENT_STRING,
  680.                     IVOLID_Volume_Label_Ptr((PCIVOLUMEID)pcvolid)));
  681.    return;
  682. }
  683. #endif