Changeset 21564 for trunk/src


Ignore:
Timestamp:
Jan 19, 2011, 10:56:46 PM (15 years ago)
Author:
dmik
Message:

kernel32: Implemented generating the high/low index values (using a CRC32 and a hash function on the fuill file name) and filling up the volume serial number in the BY_HANDLE_FILE_INFORMATION structure returned by GetFileInformationByHandle().

Location:
trunk/src/kernel32
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/hmfile.cpp

    r21329 r21564  
    4242static void ParsePath(LPCSTR lpszFileName, LPSTR lpszParsedFileName, DWORD length);
    4343
     44
     45class HMFileInfo
     46{
     47public:
     48  HMFileInfo(HANDLE hFile, LPSTR lpszFileName, PVOID lpSecurityAttributes);
     49 ~HMFileInfo();
     50
     51  char *lpszFileName;
     52  PVOID lpSecurityAttributes;
     53  DWORD dwLXOffset;
     54};
     55
     56
    4457/*****************************************************************************
    4558 * Name      : DWORD HMDeviceFileClass::CreateFile
     
    5265 * Variables :
    5366 * Result    :
    54  * Remark    : 
     67 * Remark    :
    5568 * Status    : NO_ERROR - API succeeded
    5669 *             other    - what is to be set in SetLastError
     
    7487           lpSecurityAttributes,
    7588           pHMHandleDataTemplate));
    76  
     89
    7790  ParsePath(lpFileName, filepath, sizeof(filepath));
    7891
     
    120133 * Remark    : TODO: Check if this implementation is complete and 100% correct
    121134 *                           UTC Time or Localtime ?
    122  *                   GetFileTime is changed, Returns UTC-time yet !!!!! 
     135 *                   GetFileTime is changed, Returns UTC-time yet !!!!!
    123136 * Status    : NO_ERROR - API succeeded
    124137 *             other    - what is to be set in SetLastError
     
    187200        #if 1 /* Canonicalize the path should be the right thing to do I think... */
    188201        GetFullPathNameA(lpFileName, sizeof(filepath), filepath, NULL);
    189         #else                       
     202        #else
    190203        ParsePath(lpFileName, filepath, sizeof(filepath));
    191204        #endif
     
    201214    strncpy((char *)pOFStruct->szPathName, lpFileName, OFS_MAXPATHNAME);
    202215    pOFStruct->szPathName[OFS_MAXPATHNAME-1] = 0;
    203    
    204 
    205     /* 
     216
     217
     218    /*
    206219     * Do the parse stuff now and do a quick exit.
    207      * Based on testcase (5) and MSDN: 
     220     * Based on testcase (5) and MSDN:
    208221     *      "OF_PARSE   Fills the OFSTRUCT structure but carries out no other action."
    209222     */
     
    217230        return NO_ERROR;
    218231    }
    219    
     232
    220233
    221234    hFile = OSLibDosOpenFile((LPSTR)lpFileName, fuMode);
    222    
     235
    223236    if(hFile != INVALID_HANDLE_ERROR)
    224237    {
     
    229242                    NULL,
    230243                    &filetime );
    231    
    232         /* UTC Time or Localtime ? GetFileTime Returns UTC-time yet ? !!!!! */ 
     244
     245        /* UTC Time or Localtime ? GetFileTime Returns UTC-time yet ? !!!!! */
    233246        FileTimeToDosDateTime(&filetime,
    234247                              &filedatetime[0],
    235248                              &filedatetime[1] );
    236249        memcpy(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved));
    237    
     250
    238251        if(fuMode & OF_DELETE)
    239252        {
     
    247260            hFile = HFILE_ERROR;
    248261        }
    249    
     262
    250263        if((fuMode & OF_VERIFY))
    251264        {//TODO: what's this?? we copy the time above...
     
    257270            hFile = HFILE_ERROR;
    258271        }
    259    
     272
    260273        pOFStruct->nErrCode = GetLastError();
    261274        pHMHandleData->hHMHandle = hFile;
    262    
     275
    263276        if(hFile != HFILE_ERROR) {
    264277            pHMHandleData->dwUserData = (DWORD) new HMFileInfo(hFile, (LPSTR)lpFileName, NULL);
     
    268281    else {
    269282        DWORD rc = GetLastError();
    270    
     283
    271284        if(fuMode & OF_EXIST)
    272285        {
     
    393406 * Result    : TRUE / FALSE
    394407 * Remark    :
    395  * Status    : 
     408 * Status    :
    396409 *
    397410 * Author    : SvL
     
    617630       if((nNumberOfBytesToWrite+offset) & 0xfff)
    618631           nrpages++;
    619  
     632
    620633       map->commitRange((ULONG)lpBuffer, offset & ~0xfff, FALSE, nrpages);
    621634       map->Release();
     
    697710              lpHMDeviceName, pHMHandleData, pHFI));
    698711
    699     if(OSLibDosGetFileInformationByHandle(pHMHandleData->hHMHandle,
     712    HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
     713    if(OSLibDosGetFileInformationByHandle(fileInfo->lpszFileName,
     714                                          pHMHandleData->hHMHandle,
    700715                                          pHFI))
    701716    {
     
    853868  if(fileInfo && fileInfo->dwLXOffset)
    854869  {
    855       switch(dwMoveMethod) 
     870      switch(dwMoveMethod)
    856871      {
    857872      case FILE_BEGIN:
     
    11061121 * Variables :
    11071122 * Result    : BOOLEAN
    1108  * Remark    : 
     1123 * Remark    :
    11091124 * Status    :
    11101125 *
     
    11301145//
    11311146// When the application opens a file with CreateFile and 0 for desired access,
    1132 // then we need to create a handle with limited access. 
     1147// then we need to create a handle with limited access.
    11331148//
    11341149// MSDN:
    11351150//
    1136 // If this parameter is zero, the application can query file and device attributes 
    1137 // without accessing the device. This is useful if an application wants to determine 
     1151// If this parameter is zero, the application can query file and device attributes
     1152// without accessing the device. This is useful if an application wants to determine
    11381153// the size of a floppy disk drive and the formats it supports without requiring
    11391154// a floppy in the drive. It can also be used to test for the file's or directory's
     
    11531168 * Variables :
    11541169 * Result    :
    1155  * Remark    : 
     1170 * Remark    :
    11561171 * Status    : NO_ERROR - API succeeded
    11571172 *             other    - what is to be set in SetLastError
     
    11731188           lpSecurityAttributes,
    11741189           pHMHandleDataTemplate));
    1175  
     1190
    11761191  ParsePath(lpFileName, filepath, sizeof(filepath));
    11771192
     
    12421257  WIN32_FIND_DATAA finddata;
    12431258  HANDLE hFind;
    1244    
     1259
    12451260  hFind = FindFirstFileA(fileInfo->lpszFileName, &finddata);
    12461261  if(hFind == INVALID_HANDLE_VALUE) {
     
    12901305  WIN32_FIND_DATAA finddata;
    12911306  HANDLE hFind;
    1292    
     1307
    12931308  hFind = FindFirstFileA(fileInfo->lpszFileName, &finddata);
    12941309  if(hFind == INVALID_HANDLE_VALUE) {
     
    13001315  FindClose(hFind);
    13011316
    1302   if(fileInfo->dwLXOffset) 
     1317  if(fileInfo->dwLXOffset)
    13031318  {
    13041319      //subtract the LX header and magic qword from the file size
     
    13141329 * Variables :
    13151330 * Result    : BOOLEAN
    1316  * Remark    : 
     1331 * Remark    :
    13171332 * Status    :
    13181333 *
     
    13551370HMFileInfo::HMFileInfo(HANDLE hFile, LPSTR lpszFileName, PVOID lpSecurityAttributes)
    13561371{
     1372  // get the full path (this is necessary in particular for GetFileInformationByHandle)
     1373  char fullPath[260];
     1374  if (!OSLibDosQueryPathInfo(lpszFileName, FIL_QUERYFULLNAME, fullPath, sizeof(fullPath))) {
     1375      lpszFileName = fullPath;
     1376  }
     1377
    13571378  this->lpszFileName = (LPSTR)malloc(strlen(lpszFileName)+1);
    13581379  if(!this->lpszFileName) {
     
    13661387  //an LX header. We need to skip that to present the original file to the
    13671388  //caller
    1368   if(hFile && !stricmp(lpszFileName + strlen(lpszFileName) - 4, ".EXE")) 
     1389  if(hFile && !stricmp(lpszFileName + strlen(lpszFileName) - 4, ".EXE"))
    13691390  {
    13701391      ULONG action, ulRead, signature, ulFileSize;
     
    13851406
    13861407      //Make sure it's an LX executable before continueing
    1387       if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || (WORD)signature != IMAGE_OS2_SIGNATURE_LX) 
     1408      if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || (WORD)signature != IMAGE_OS2_SIGNATURE_LX)
    13881409      {
    13891410          goto failure;
  • trunk/src/kernel32/hmfile.h

    r21302 r21564  
    2424#include "HMOpen32.h"
    2525
    26 
    27 class HMFileInfo
    28 {
    29 public:
    30   HMFileInfo(HANDLE hFile, LPSTR lpszFileName, PVOID lpSecurityAttributes);
    31  ~HMFileInfo();
    32 
    33   char *lpszFileName;
    34   PVOID lpSecurityAttributes;
    35   DWORD dwLXOffset;
    36 };
    3726
    3827/*****************************************************************************
  • trunk/src/kernel32/oslibdos.cpp

    r21525 r21564  
    9595BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d );
    9696
     97static ULONG sdbm(const char *str);
     98static ULONG crc32str(const char *psz);
    9799
    98100char* ODINHelperStripUNC(char* strUNC)
     
    13931395//******************************************************************************
    13941396//******************************************************************************
    1395 BOOL OSLibDosGetFileInformationByHandle(DWORD hFile, BY_HANDLE_FILE_INFORMATION* pInfo)
     1397BOOL OSLibDosGetFileInformationByHandle(LPCSTR lpFileName, DWORD hFile, BY_HANDLE_FILE_INFORMATION* pInfo)
    13961398{
    13971399 APIRET       rc;
     
    14351437            pInfo->nFileSizeHigh = statusL.cbFile.ulHi;
    14361438            pInfo->nFileSizeLow  = statusL.cbFile.ulLo;
    1437             pInfo->dwVolumeSerialNumber = 0; //todo
     1439            pInfo->dwVolumeSerialNumber = 0;
    14381440            pInfo->nNumberOfLinks = 1;
    14391441            pInfo->nFileIndexHigh = 0;
     
    14741476
    14751477            pInfo->nFileSizeHigh = 0;
    1476             pInfo->nFileSizeLow = status.cbFile;
    1477             pInfo->dwVolumeSerialNumber = 0; //todo
     1478            pInfo->nFileSizeLow  = status.cbFile;
     1479            pInfo->dwVolumeSerialNumber = 0;
    14781480            pInfo->nNumberOfLinks = 1;
    14791481            pInfo->nFileIndexHigh = 0;
    1480             pInfo->nFileIndexLow = 0;
     1482            pInfo->nFileIndexLow  = 0;
    14811483        }
    14821484   }
     
    14851487        return FALSE;
    14861488   }
     1489
     1490   if(lpFileName &&
     1491      // must be the full path
     1492      *lpFileName && lpFileName[1] == ':') {
     1493       // get the volume serial
     1494       ULONG disk = toupper(*lpFileName) - 'A' + 1;
     1495       FSINFO fsinfo;
     1496       rc = DosQueryFSInfo(disk, FSIL_VOLSER, &fsinfo, sizeof(fsinfo));
     1497       if(!rc) {
     1498           pInfo->dwVolumeSerialNumber = *(USHORT *)&fsinfo.ftimeCreation;
     1499           pInfo->dwVolumeSerialNumber <<= 16;
     1500           pInfo->dwVolumeSerialNumber |= *(USHORT *)&fsinfo.fdateCreation;
     1501       }
     1502       // fake the index number
     1503       pInfo->nFileIndexHigh = crc32str(lpFileName);
     1504       pInfo->nFileIndexLow = sdbm(lpFileName);
     1505   }
     1506
    14871507   SetLastError(ERROR_SUCCESS_W);
    14881508   return TRUE;
     
    33763396//******************************************************************************
    33773397
     3398/* sdbm:
     3399   This algorithm was created for sdbm (a public-domain reimplementation of
     3400   ndbm) database library. it was found to do well in scrambling bits,
     3401   causing better distribution of the keys and fewer splits. it also happens
     3402   to be a good general hashing function with good distribution. the actual
     3403   function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
     3404   is the faster version used in gawk. [there is even a faster, duff-device
     3405   version] the magic constant 65599 was picked out of thin air while
     3406   experimenting with different constants, and turns out to be a prime.
     3407   this is one of the algorithms used in berkeley db (see sleepycat) and
     3408   elsewhere. */
     3409static ULONG sdbm(const char *str)
     3410{
     3411    ULONG hash = 0;
     3412    ULONG c;
     3413
     3414    while ((c = *(unsigned const char *)str++))
     3415        hash = c + (hash << 6) + (hash << 16) - hash;
     3416
     3417    return hash;
     3418}
     3419
     3420/*-
     3421 *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
     3422 *  code or tables extracted from it, as desired without restriction.
     3423 *
     3424 *  First, the polynomial itself and its table of feedback terms.  The
     3425 *  polynomial is
     3426 *  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
     3427 *
     3428 *  Note that we take it "backwards" and put the highest-order term in
     3429 *  the lowest-order bit.  The X^32 term is "implied"; the LSB is the
     3430 *  X^31 term, etc.  The X^0 term (usually shown as "+1") results in
     3431 *  the MSB being 1
     3432 *
     3433 *  Note that the usual hardware shift register implementation, which
     3434 *  is what we're using (we're merely optimizing it by doing eight-bit
     3435 *  chunks at a time) shifts bits into the lowest-order term.  In our
     3436 *  implementation, that means shifting towards the right.  Why do we
     3437 *  do it this way?  Because the calculated CRC must be transmitted in
     3438 *  order from highest-order term to lowest-order term.  UARTs transmit
     3439 *  characters in order from LSB to MSB.  By storing the CRC this way
     3440 *  we hand it to the UART in the order low-byte to high-byte; the UART
     3441 *  sends each low-bit to hight-bit; and the result is transmission bit
     3442 *  by bit from highest- to lowest-order term without requiring any bit
     3443 *  shuffling on our part.  Reception works similarly
     3444 *
     3445 *  The feedback terms table consists of 256, 32-bit entries.  Notes
     3446 *
     3447 *      The table can be generated at runtime if desired; code to do so
     3448 *      is shown later.  It might not be obvious, but the feedback
     3449 *      terms simply represent the results of eight shift/xor opera
     3450 *      tions for all combinations of data and CRC register values
     3451 *
     3452 *      The values must be right-shifted by eight bits by the "updcrc
     3453 *      logic; the shift must be unsigned (bring in zeroes).  On some
     3454 *      hardware you could probably optimize the shift in assembler by
     3455 *      using byte-swap instructions
     3456 *      polynomial $edb88320
     3457 *
     3458 *
     3459 * CRC32 code derived from work by Gary S. Brown.
     3460 */
     3461
     3462static const ULONG crc32_tab[] = {
     3463        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
     3464        0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
     3465        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
     3466        0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
     3467        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
     3468        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
     3469        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
     3470        0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
     3471        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
     3472        0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
     3473        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
     3474        0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
     3475        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
     3476        0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
     3477        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
     3478        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
     3479        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
     3480        0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
     3481        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
     3482        0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
     3483        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
     3484        0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
     3485        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
     3486        0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
     3487        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
     3488        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
     3489        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
     3490        0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
     3491        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
     3492        0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
     3493        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
     3494        0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
     3495        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
     3496        0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
     3497        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
     3498        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
     3499        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
     3500        0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
     3501        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
     3502        0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
     3503        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
     3504        0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
     3505        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
     3506};
     3507
     3508static ULONG
     3509crc32str(const char *psz)
     3510{
     3511        const UCHAR *p;
     3512        ULONG crc;
     3513
     3514        p = (const UCHAR *)psz;
     3515        crc = ~0U;
     3516
     3517        while (*p)
     3518                crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
     3519
     3520        return crc ^ ~0U;
     3521}
     3522
  • trunk/src/kernel32/oslibdos.h

    r21329 r21564  
    102102BOOL  OSLibDosWrite(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesWritten);
    103103
    104 BOOL  OSLibDosGetFileInformationByHandle(DWORD hFile, BY_HANDLE_FILE_INFORMATION* pHFI);
     104BOOL  OSLibDosGetFileInformationByHandle(LPCSTR lpFileName, DWORD hFile, BY_HANDLE_FILE_INFORMATION* pHFI);
    105105
    106106BOOL  OSLibDosSetFileTime(DWORD hFile, LPFILETIME pFT1,
Note: See TracChangeset for help on using the changeset viewer.