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 */ 17 const int driveCount = ('Z'-'A')+1+1; 18 19 class VDir 20 { 21 public: 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 60 protected: 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 127 VDir::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 135 void 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 190 int 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 224 void 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 236 void 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 248 void 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 261 int 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 295 void 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 308 inline BOOL IsPathSep(char ch) 309 { 310 return (ch == '\\' || ch == '/'); 311 } 312 313 inline 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 NULL 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 327 inline 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 403 char *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 475 int 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 499 DWORD 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 511 LPSTR 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 536 inline BOOL IsPathSep(WCHAR ch) 537 { 538 return (ch == '\\' || ch == '/'); 539 } 540 541 inline 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 NULL 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 555 inline 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 631 WCHAR* 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 702 int 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