perl/win32/vdir.h
<<
>>
Prefs
   1/* vdir.h
   2 *
   3 * (c) 1999 Microsoft Corporation. All rights reserved. 
   4 * Portions (c) 1999 ActiveState Tool Corp, http://www.ActiveState.com/
   5 *
   6 *    You may distribute under the terms of either the GNU General Public
   7 *    License or the Artistic License, as specified in the README file.
   8 */
   9
  10#ifndef ___VDir_H___
  11#define ___VDir_H___
  12
  13/*
  14 * Allow one slot for each possible drive letter
  15 * and one additional slot for a UNC name
  16 */
  17const int driveCount = ('Z'-'A')+1+1;
  18
  19class VDir
  20{
  21public:
  22    VDir(int bManageDir = 1);
  23    ~VDir() {};
  24
  25    void Init(VDir* pDir, VMem *pMem);
  26    void SetDefaultA(char const *pDefault);
  27    void SetDefaultW(WCHAR const *pDefault);
  28    char* MapPathA(const char *pInName);
  29    WCHAR* MapPathW(const WCHAR *pInName);
  30    int SetCurrentDirectoryA(char *lpBuffer);
  31    int SetCurrentDirectoryW(WCHAR *lpBuffer);
  32    inline int GetDefault(void) { return nDefault; };
  33
  34    inline char* GetCurrentDirectoryA(int dwBufSize, char *lpBuffer)
  35    {
  36        char* ptr = dirTableA[nDefault];
  37        while (--dwBufSize)
  38        {
  39            if ((*lpBuffer++ = *ptr++) == '\0')
  40                break;
  41        }
  42        *lpBuffer = '\0';
  43        return /* unused */ NULL;
  44    };
  45    inline WCHAR* GetCurrentDirectoryW(int dwBufSize, WCHAR *lpBuffer)
  46    {
  47        WCHAR* ptr = dirTableW[nDefault];
  48        while (--dwBufSize)
  49        {
  50            if ((*lpBuffer++ = *ptr++) == '\0')
  51                break;
  52        }
  53        *lpBuffer = '\0';
  54        return /* unused */ NULL;
  55    };
  56
  57    DWORD CalculateEnvironmentSpace(void);
  58    LPSTR BuildEnvironmentSpace(LPSTR lpStr);
  59
  60protected:
  61    int SetDirA(char const *pPath, int index);
  62    int SetDirW(WCHAR const *pPath, int index);
  63    void FromEnvA(char *pEnv, int index);
  64    void FromEnvW(WCHAR *pEnv, int index);
  65
  66    inline const char *GetDefaultDirA(void)
  67    {
  68        return dirTableA[nDefault];
  69    };
  70    inline void SetDefaultDirA(char const *pPath, int index)
  71    {
  72        SetDirA(pPath, index);
  73        nDefault = index;
  74    };
  75    inline const WCHAR *GetDefaultDirW(void)
  76    {
  77        return dirTableW[nDefault];
  78    };
  79    inline void SetDefaultDirW(WCHAR const *pPath, int index)
  80    {
  81        SetDirW(pPath, index);
  82        nDefault = index;
  83    };
  84    inline const char *GetDirA(int index)
  85    {
  86        char *ptr = dirTableA[index];
  87        if (!ptr) {
  88            /* simulate the existance of this drive */
  89            ptr = szLocalBufferA;
  90            ptr[0] = 'A' + index;
  91            ptr[1] = ':';
  92            ptr[2] = '\\';
  93            ptr[3] = 0;
  94        }
  95        return ptr;
  96    };
  97    inline const WCHAR *GetDirW(int index)
  98    {
  99        WCHAR *ptr = dirTableW[index];
 100        if (!ptr) {
 101            /* simulate the existance of this drive */
 102            ptr = szLocalBufferW;
 103            ptr[0] = 'A' + index;
 104            ptr[1] = ':';
 105            ptr[2] = '\\';
 106            ptr[3] = 0;
 107        }
 108        return ptr;
 109    };
 110
 111    inline int DriveIndex(char chr)
 112    {
 113        if (chr == '\\' || chr == '/')
 114            return ('Z'-'A')+1;
 115        return (chr | 0x20)-'a';
 116    };
 117
 118    VMem *pMem;
 119    int nDefault, bManageDirectory;
 120    char *dirTableA[driveCount];
 121    char szLocalBufferA[MAX_PATH+1];
 122    WCHAR *dirTableW[driveCount];
 123    WCHAR szLocalBufferW[MAX_PATH+1];
 124};
 125
 126
 127VDir::VDir(int bManageDir /* = 1 */)
 128{
 129    nDefault = 0;
 130    bManageDirectory = bManageDir;
 131    memset(dirTableA, 0, sizeof(dirTableA));
 132    memset(dirTableW, 0, sizeof(dirTableW));
 133}
 134
 135void VDir::Init(VDir* pDir, VMem *p)
 136{
 137    int index;
 138
 139    pMem = p;
 140    if (pDir) {
 141        for (index = 0; index < driveCount; ++index) {
 142            SetDirW(pDir->GetDirW(index), index);
 143        }
 144        nDefault = pDir->GetDefault();
 145    }
 146    else {
 147        int bSave = bManageDirectory;
 148        DWORD driveBits = GetLogicalDrives();
 149        OSVERSIONINFO osver;
 150
 151        memset(&osver, 0, sizeof(osver));
 152        osver.dwOSVersionInfoSize = sizeof(osver);
 153        GetVersionEx(&osver);
 154
 155        bManageDirectory = 0;
 156        if (osver.dwMajorVersion < 5) {
 157            char szBuffer[MAX_PATH*driveCount];
 158            if (GetLogicalDriveStringsA(sizeof(szBuffer), szBuffer)) {
 159                char* pEnv = (char*)GetEnvironmentStringsA();
 160                char* ptr = szBuffer;
 161                for (index = 0; index < driveCount; ++index) {
 162                    if (driveBits & (1<<index)) {
 163                        ptr += SetDirA(ptr, index) + 1;
 164                        FromEnvA(pEnv, index);
 165                    }
 166                }
 167                FreeEnvironmentStringsA(pEnv);
 168            }
 169            SetDefaultA(".");
 170        }
 171        else { /* Windows 2000 or later */
 172            WCHAR szBuffer[MAX_PATH*driveCount];
 173            if (GetLogicalDriveStringsW(sizeof(szBuffer), szBuffer)) {
 174                WCHAR* pEnv = GetEnvironmentStringsW();
 175                WCHAR* ptr = szBuffer;
 176                for (index = 0; index < driveCount; ++index) {
 177                    if (driveBits & (1<<index)) {
 178                        ptr += SetDirW(ptr, index) + 1;
 179                        FromEnvW(pEnv, index);
 180                    }
 181                }
 182                FreeEnvironmentStringsW(pEnv);
 183            }
 184            SetDefaultW(L".");
 185        }
 186        bManageDirectory = bSave;
 187  }
 188}
 189
 190int VDir::SetDirA(char const *pPath, int index)
 191{
 192    char chr, *ptr;
 193    int length = 0;
 194    WCHAR wBuffer[MAX_PATH+1];
 195    if (index < driveCount && pPath != NULL) {
 196        length = strlen(pPath);
 197        pMem->Free(dirTableA[index]);
 198        ptr = dirTableA[index] = (char*)pMem->Malloc(length+2);
 199        if (ptr != NULL) {
 200            strcpy(ptr, pPath);
 201            ptr += length-1;
 202            chr = *ptr++;
 203            if (chr != '\\' && chr != '/') {
 204                *ptr++ = '\\';
 205                *ptr = '\0';
 206            }
 207            MultiByteToWideChar(CP_ACP, 0, dirTableA[index], -1,
 208                    wBuffer, (sizeof(wBuffer)/sizeof(WCHAR)));
 209            length = wcslen(wBuffer);
 210            pMem->Free(dirTableW[index]);
 211            dirTableW[index] = (WCHAR*)pMem->Malloc((length+1)*2);
 212            if (dirTableW[index] != NULL) {
 213                wcscpy(dirTableW[index], wBuffer);
 214            }
 215        }
 216    }
 217
 218    if(bManageDirectory)
 219        ::SetCurrentDirectoryA(pPath);
 220
 221    return length;
 222}
 223
 224void VDir::FromEnvA(char *pEnv, int index)
 225{   /* gets the directory for index from the environment variable. */
 226    while (*pEnv != '\0') {
 227        if ((pEnv[0] == '=') && (DriveIndex(pEnv[1]) == index)) {
 228            SetDirA(&pEnv[4], index);
 229            break;
 230        }
 231        else
 232            pEnv += strlen(pEnv)+1;
 233    }
 234}
 235
 236void VDir::FromEnvW(WCHAR *pEnv, int index)
 237{   /* gets the directory for index from the environment variable. */
 238    while (*pEnv != '\0') {
 239        if ((pEnv[0] == '=') && (DriveIndex((char)pEnv[1]) == index)) {
 240            SetDirW(&pEnv[4], index);
 241            break;
 242        }
 243        else
 244            pEnv += wcslen(pEnv)+1;
 245    }
 246}
 247
 248void VDir::SetDefaultA(char const *pDefault)
 249{
 250    char szBuffer[MAX_PATH+1];
 251    char *pPtr;
 252
 253    if (GetFullPathNameA(pDefault, sizeof(szBuffer), szBuffer, &pPtr)) {
 254        if (*pDefault != '.' && pPtr != NULL)
 255            *pPtr = '\0';
 256
 257        SetDefaultDirA(szBuffer, DriveIndex(szBuffer[0]));
 258    }
 259}
 260
 261int VDir::SetDirW(WCHAR const *pPath, int index)
 262{
 263    WCHAR chr, *ptr;
 264    int length = 0;
 265    if (index < driveCount && pPath != NULL) {
 266        length = wcslen(pPath);
 267        pMem->Free(dirTableW[index]);
 268        ptr = dirTableW[index] = (WCHAR*)pMem->Malloc((length+2)*2);
 269        if (ptr != NULL) {
 270            char *ansi;
 271            wcscpy(ptr, pPath);
 272            ptr += length-1;
 273            chr = *ptr++;
 274            if (chr != '\\' && chr != '/') {
 275                *ptr++ = '\\';
 276                *ptr = '\0';
 277            }
 278            ansi = win32_ansipath(dirTableW[index]);
 279            length = strlen(ansi);
 280            pMem->Free(dirTableA[index]);
 281            dirTableA[index] = (char*)pMem->Malloc(length+1);
 282            if (dirTableA[index] != NULL) {
 283                strcpy(dirTableA[index], ansi);
 284            }
 285            win32_free(ansi);
 286        }
 287    }
 288
 289    if(bManageDirectory)
 290        ::SetCurrentDirectoryW(pPath);
 291
 292    return length;
 293}
 294
 295void VDir::SetDefaultW(WCHAR const *pDefault)
 296{
 297    WCHAR szBuffer[MAX_PATH+1];
 298    WCHAR *pPtr;
 299
 300    if (GetFullPathNameW(pDefault, (sizeof(szBuffer)/sizeof(WCHAR)), szBuffer, &pPtr)) {
 301        if (*pDefault != '.' && pPtr != NULL)
 302            *pPtr = '\0';
 303
 304        SetDefaultDirW(szBuffer, DriveIndex((char)szBuffer[0]));
 305    }
 306}
 307
 308inline BOOL IsPathSep(char ch)
 309{
 310    return (ch == '\\' || ch == '/');
 311}
 312
 313inline void DoGetFullPathNameA(char* lpBuffer, DWORD dwSize, char* Dest)
 314{
 315    char *pPtr;
 316
 317    /*
 318     * On WinNT GetFullPathName does not fail, (or at least always
 319     * succeeds when the drive is valid) WinNT does set *Dest to Nullch
 320     * On Win98 GetFullPathName will set last error if it fails, but
 321     * does not touch *Dest
 322     */
 323    *Dest = '\0';
 324    GetFullPathNameA(lpBuffer, dwSize, Dest, &pPtr);
 325}
 326
 327inline bool IsSpecialFileName(const char* pName)
 328{
 329    /* specical file names are devices that the system can open
 330     * these include AUX, CON, NUL, PRN, COMx, LPTx, CLOCK$, CONIN$, CONOUT$
 331     * (x is a single digit, and names are case-insensitive)
 332     */
 333    char ch = (pName[0] & ~0x20);
 334    switch (ch)
 335    {
 336        case 'A': /* AUX */
 337            if (((pName[1] & ~0x20) == 'U')
 338                && ((pName[2] & ~0x20) == 'X')
 339                && !pName[3])
 340                    return true;
 341            break;
 342        case 'C': /* CLOCK$, COMx,  CON, CONIN$ CONOUT$ */
 343            ch = (pName[1] & ~0x20);
 344            switch (ch)
 345            {
 346                case 'L': /* CLOCK$ */
 347                    if (((pName[2] & ~0x20) == 'O')
 348                        && ((pName[3] & ~0x20) == 'C')
 349                        && ((pName[4] & ~0x20) == 'K')
 350                        && (pName[5] == '$')
 351                        && !pName[6])
 352                            return true;
 353                    break;
 354                case 'O': /* COMx,  CON, CONIN$ CONOUT$ */
 355                    if ((pName[2] & ~0x20) == 'M') {
 356                        if ((pName[3] >= '1') && (pName[3] <= '9')
 357                            && !pName[4])
 358                            return true;
 359                    }
 360                    else if ((pName[2] & ~0x20) == 'N') {
 361                        if (!pName[3])
 362                            return true;
 363                        else if ((pName[3] & ~0x20) == 'I') {
 364                            if (((pName[4] & ~0x20) == 'N')
 365                                && (pName[5] == '$')
 366                                && !pName[6])
 367                            return true;
 368                        }
 369                        else if ((pName[3] & ~0x20) == 'O') {
 370                            if (((pName[4] & ~0x20) == 'U')
 371                                && ((pName[5] & ~0x20) == 'T')
 372                                && (pName[6] == '$')
 373                                && !pName[7])
 374                            return true;
 375                        }
 376                    }
 377                    break;
 378            }
 379            break;
 380        case 'L': /* LPTx */
 381            if (((pName[1] & ~0x20) == 'U')
 382                && ((pName[2] & ~0x20) == 'X')
 383                && (pName[3] >= '1') && (pName[3] <= '9')
 384                && !pName[4])
 385                    return true;
 386            break;
 387        case 'N': /* NUL */
 388            if (((pName[1] & ~0x20) == 'U')
 389                && ((pName[2] & ~0x20) == 'L')
 390                && !pName[3])
 391                    return true;
 392            break;
 393        case 'P': /* PRN */
 394            if (((pName[1] & ~0x20) == 'R')
 395                && ((pName[2] & ~0x20) == 'N')
 396                && !pName[3])
 397                    return true;
 398            break;
 399    }
 400    return false;
 401}
 402
 403char *VDir::MapPathA(const char *pInName)
 404{   /*
 405     * possiblities -- relative path or absolute path with or without drive letter
 406     * OR UNC name
 407     */
 408    char szBuffer[(MAX_PATH+1)*2];
 409    char szlBuf[MAX_PATH+1];
 410    int length = strlen(pInName);
 411
 412    if (!length)
 413        return (char*)pInName;
 414
 415    if (length > MAX_PATH) {
 416        strncpy(szlBuf, pInName, MAX_PATH);
 417        if (IsPathSep(pInName[0]) && !IsPathSep(pInName[1])) {   
 418            /* absolute path - reduce length by 2 for drive specifier */
 419            szlBuf[MAX_PATH-2] = '\0';
 420        }
 421        else
 422            szlBuf[MAX_PATH] = '\0';
 423        pInName = szlBuf;
 424    }
 425    /* strlen(pInName) is now <= MAX_PATH */
 426
 427    if (pInName[1] == ':') {
 428        /* has drive letter */
 429        if (IsPathSep(pInName[2])) {
 430            /* absolute with drive letter */
 431            DoGetFullPathNameA((char*)pInName, sizeof(szLocalBufferA), szLocalBufferA);
 432        }
 433        else {
 434            /* relative path with drive letter */
 435            strcpy(szBuffer, GetDirA(DriveIndex(*pInName)));
 436            strcat(szBuffer, &pInName[2]);
 437            if(strlen(szBuffer) > MAX_PATH)
 438                szBuffer[MAX_PATH] = '\0';
 439
 440            DoGetFullPathNameA(szBuffer, sizeof(szLocalBufferA), szLocalBufferA);
 441        }
 442    }
 443    else {
 444        /* no drive letter */
 445        if (IsPathSep(pInName[1]) && IsPathSep(pInName[0])) {
 446            /* UNC name */
 447            DoGetFullPathNameA((char*)pInName, sizeof(szLocalBufferA), szLocalBufferA);
 448        }
 449        else {
 450            strcpy(szBuffer, GetDefaultDirA());
 451            if (IsPathSep(pInName[0])) {
 452                /* absolute path */
 453                strcpy(&szBuffer[2], pInName);
 454                DoGetFullPathNameA(szBuffer, sizeof(szLocalBufferA), szLocalBufferA);
 455            }
 456            else {
 457                /* relative path */
 458                if (IsSpecialFileName(pInName)) {
 459                    return (char*)pInName;
 460                }
 461                else {
 462                    strcat(szBuffer, pInName);
 463                    if (strlen(szBuffer) > MAX_PATH)
 464                        szBuffer[MAX_PATH] = '\0';
 465
 466                    DoGetFullPathNameA(szBuffer, sizeof(szLocalBufferA), szLocalBufferA);
 467                }
 468            }
 469        }
 470    }
 471
 472    return szLocalBufferA;
 473}
 474
 475int VDir::SetCurrentDirectoryA(char *lpBuffer)
 476{
 477    char *pPtr;
 478    int length, nRet = -1;
 479
 480    pPtr = MapPathA(lpBuffer);
 481    length = strlen(pPtr);
 482    if(length > 3 && IsPathSep(pPtr[length-1])) {
 483        /* don't remove the trailing slash from 'x:\'  */
 484        pPtr[length-1] = '\0';
 485    }
 486
 487    DWORD r = GetFileAttributesA(pPtr);
 488    if ((r != 0xffffffff) && (r & FILE_ATTRIBUTE_DIRECTORY))
 489    {
 490        char szBuffer[(MAX_PATH+1)*2];
 491        DoGetFullPathNameA(pPtr, sizeof(szBuffer), szBuffer);
 492        SetDefaultDirA(szBuffer, DriveIndex(szBuffer[0]));
 493        nRet = 0;
 494    }
 495
 496    return nRet;
 497}
 498
 499DWORD VDir::CalculateEnvironmentSpace(void)
 500{   /* the current directory environment strings are stored as '=D:=d:\path' */
 501    int index;
 502    DWORD dwSize = 0;
 503    for (index = 0; index < driveCount; ++index) {
 504        if (dirTableA[index] != NULL) {
 505            dwSize += strlen(dirTableA[index]) + 5;  /* add 1 for trailing NULL and 4 for '=D:=' */
 506        }
 507    }
 508    return dwSize;
 509}
 510
 511LPSTR VDir::BuildEnvironmentSpace(LPSTR lpStr)
 512{   /* store the current directory environment strings as '=D:=d:\path' */
 513    int index, length;
 514    LPSTR lpDirStr;
 515    for (index = 0; index < driveCount; ++index) {
 516        lpDirStr = dirTableA[index];
 517        if (lpDirStr != NULL) {
 518            lpStr[0] = '=';
 519            lpStr[1] = lpDirStr[0];
 520            lpStr[2] = '\0';
 521            CharUpper(&lpStr[1]);
 522            lpStr[2] = ':';
 523            lpStr[3] = '=';
 524            strcpy(&lpStr[4], lpDirStr);
 525            length = strlen(lpDirStr);
 526            lpStr += length + 5; /* add 1 for trailing NULL and 4 for '=D:=' */
 527            if (length > 3 && IsPathSep(lpStr[-2])) {
 528                lpStr[-2] = '\0';   /* remove the trailing path separator */
 529                --lpStr;
 530            }
 531        }
 532    }
 533    return lpStr;
 534}
 535
 536inline BOOL IsPathSep(WCHAR ch)
 537{
 538    return (ch == '\\' || ch == '/');
 539}
 540
 541inline void DoGetFullPathNameW(WCHAR* lpBuffer, DWORD dwSize, WCHAR* Dest)
 542{
 543    WCHAR *pPtr;
 544
 545    /*
 546     * On WinNT GetFullPathName does not fail, (or at least always
 547     * succeeds when the drive is valid) WinNT does set *Dest to Nullch
 548     * On Win98 GetFullPathName will set last error if it fails, but
 549     * does not touch *Dest
 550     */
 551    *Dest = '\0';
 552    GetFullPathNameW(lpBuffer, dwSize, Dest, &pPtr);
 553}
 554
 555inline bool IsSpecialFileName(const WCHAR* pName)
 556{
 557    /* specical file names are devices that the system can open
 558     * these include AUX, CON, NUL, PRN, COMx, LPTx, CLOCK$, CONIN$, CONOUT$
 559     * (x is a single digit, and names are case-insensitive)
 560     */
 561    WCHAR ch = (pName[0] & ~0x20);
 562    switch (ch)
 563    {
 564        case 'A': /* AUX */
 565            if (((pName[1] & ~0x20) == 'U')
 566                && ((pName[2] & ~0x20) == 'X')
 567                && !pName[3])
 568                    return true;
 569            break;
 570        case 'C': /* CLOCK$, COMx,  CON, CONIN$ CONOUT$ */
 571            ch = (pName[1] & ~0x20);
 572            switch (ch)
 573            {
 574                case 'L': /* CLOCK$ */
 575                    if (((pName[2] & ~0x20) == 'O')
 576                        && ((pName[3] & ~0x20) == 'C')
 577                        && ((pName[4] & ~0x20) == 'K')
 578                        && (pName[5] == '$')
 579                        && !pName[6])
 580                            return true;
 581                    break;
 582                case 'O': /* COMx,  CON, CONIN$ CONOUT$ */
 583                    if ((pName[2] & ~0x20) == 'M') {
 584                        if ((pName[3] >= '1') && (pName[3] <= '9')
 585                            && !pName[4])
 586                            return true;
 587                    }
 588                    else if ((pName[2] & ~0x20) == 'N') {
 589                        if (!pName[3])
 590                            return true;
 591                        else if ((pName[3] & ~0x20) == 'I') {
 592                            if (((pName[4] & ~0x20) == 'N')
 593                                && (pName[5] == '$')
 594                                && !pName[6])
 595                            return true;
 596                        }
 597                        else if ((pName[3] & ~0x20) == 'O') {
 598                            if (((pName[4] & ~0x20) == 'U')
 599                                && ((pName[5] & ~0x20) == 'T')
 600                                && (pName[6] == '$')
 601                                && !pName[7])
 602                            return true;
 603                        }
 604                    }
 605                    break;
 606            }
 607            break;
 608        case 'L': /* LPTx */
 609            if (((pName[1] & ~0x20) == 'U')
 610                && ((pName[2] & ~0x20) == 'X')
 611                && (pName[3] >= '1') && (pName[3] <= '9')
 612                && !pName[4])
 613                    return true;
 614            break;
 615        case 'N': /* NUL */
 616            if (((pName[1] & ~0x20) == 'U')
 617                && ((pName[2] & ~0x20) == 'L')
 618                && !pName[3])
 619                    return true;
 620            break;
 621        case 'P': /* PRN */
 622            if (((pName[1] & ~0x20) == 'R')
 623                && ((pName[2] & ~0x20) == 'N')
 624                && !pName[3])
 625                    return true;
 626            break;
 627    }
 628    return false;
 629}
 630
 631WCHAR* VDir::MapPathW(const WCHAR *pInName)
 632{   /*
 633     * possiblities -- relative path or absolute path with or without drive letter
 634     * OR UNC name
 635     */
 636    WCHAR szBuffer[(MAX_PATH+1)*2];
 637    WCHAR szlBuf[MAX_PATH+1];
 638    int length = wcslen(pInName);
 639
 640    if (!length)
 641        return (WCHAR*)pInName;
 642
 643    if (length > MAX_PATH) {
 644        wcsncpy(szlBuf, pInName, MAX_PATH);
 645        if (IsPathSep(pInName[0]) && !IsPathSep(pInName[1])) {   
 646            /* absolute path - reduce length by 2 for drive specifier */
 647            szlBuf[MAX_PATH-2] = '\0';
 648        }
 649        else
 650            szlBuf[MAX_PATH] = '\0';
 651        pInName = szlBuf;
 652    }
 653    /* strlen(pInName) is now <= MAX_PATH */
 654
 655    if (pInName[1] == ':') {
 656        /* has drive letter */
 657        if (IsPathSep(pInName[2])) {
 658            /* absolute with drive letter */
 659            DoGetFullPathNameW((WCHAR*)pInName, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
 660        }
 661        else {
 662            /* relative path with drive letter */
 663            wcscpy(szBuffer, GetDirW(DriveIndex((char)*pInName)));
 664            wcscat(szBuffer, &pInName[2]);
 665            if(wcslen(szBuffer) > MAX_PATH)
 666                szBuffer[MAX_PATH] = '\0';
 667
 668            DoGetFullPathNameW(szBuffer, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
 669        }
 670    }
 671    else {
 672        /* no drive letter */
 673        if (IsPathSep(pInName[1]) && IsPathSep(pInName[0])) {
 674            /* UNC name */
 675            DoGetFullPathNameW((WCHAR*)pInName, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
 676        }
 677        else {
 678            wcscpy(szBuffer, GetDefaultDirW());
 679            if (IsPathSep(pInName[0])) {
 680                /* absolute path */
 681                wcscpy(&szBuffer[2], pInName);
 682                DoGetFullPathNameW(szBuffer, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
 683            }
 684            else {
 685                /* relative path */
 686                if (IsSpecialFileName(pInName)) {
 687                    return (WCHAR*)pInName;
 688                }
 689                else {
 690                    wcscat(szBuffer, pInName);
 691                    if (wcslen(szBuffer) > MAX_PATH)
 692                        szBuffer[MAX_PATH] = '\0';
 693
 694                    DoGetFullPathNameW(szBuffer, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
 695                }
 696            }
 697        }
 698    }
 699    return szLocalBufferW;
 700}
 701
 702int VDir::SetCurrentDirectoryW(WCHAR *lpBuffer)
 703{
 704    WCHAR *pPtr;
 705    int length, nRet = -1;
 706
 707    pPtr = MapPathW(lpBuffer);
 708    length = wcslen(pPtr);
 709    if(length > 3 && IsPathSep(pPtr[length-1])) {
 710        /* don't remove the trailing slash from 'x:\'  */
 711        pPtr[length-1] = '\0';
 712    }
 713
 714    DWORD r = GetFileAttributesW(pPtr);
 715    if ((r != 0xffffffff) && (r & FILE_ATTRIBUTE_DIRECTORY))
 716    {
 717        WCHAR wBuffer[(MAX_PATH+1)*2];
 718        DoGetFullPathNameW(pPtr, (sizeof(wBuffer)/sizeof(WCHAR)), wBuffer);
 719        SetDefaultDirW(wBuffer, DriveIndex((char)wBuffer[0]));
 720        nRet = 0;
 721    }
 722
 723    return nRet;
 724}
 725
 726#endif  /* ___VDir_H___ */
 727
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.