Changeset 76108 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Dec 10, 2018 12:01:34 PM (6 years ago)
- Location:
- trunk/src/VBox/Additions/os2/VBoxSF
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSF.cpp
r75558 r76108 189 189 190 190 /** 191 * Allocates a SHFLSTRING buffer .191 * Allocates a SHFLSTRING buffer (UTF-16). 192 192 * 193 193 * @returns Pointer to a SHFLSTRING buffer, NULL if out of memory. 194 * @param cchLength The desired string buffer length (excluding terminator). 195 */ 196 PSHFLSTRING vboxSfOs2StrAlloc(size_t cchLength) 197 { 198 AssertReturn(cchLength <= 0x1000, NULL); 199 200 PSHFLSTRING pStr = (PSHFLSTRING)VbglR0PhysHeapAlloc(SHFLSTRING_HEADER_SIZE + cchLength + 1); 194 * @param cwcLength The desired string buffer length in UTF-16 units 195 * (excluding terminator). 196 */ 197 PSHFLSTRING vboxSfOs2StrAlloc(size_t cwcLength) 198 { 199 AssertReturn(cwcLength <= 0x1000, NULL); 200 uint16_t cb = (uint16_t)cwcLength + 1; 201 cb *= sizeof(RTUTF16); 202 203 PSHFLSTRING pStr = (PSHFLSTRING)VbglR0PhysHeapAlloc(SHFLSTRING_HEADER_SIZE + cb); 201 204 if (pStr) 202 205 { 203 pStr->u16Size = (uint16_t)(cchLength + 1);204 pStr->u16Length = 0;205 pStr->String. ach[0] = '\0';206 pStr->u16Size = cb; 207 pStr->u16Length = 0; 208 pStr->String.utf16[0] = '\0'; 206 209 return pStr; 207 210 } … … 211 214 212 215 /** 213 * Duplicates a UTF-8 string into a SHFLSTRING buffer.216 * Duplicates a shared folders string buffer (UTF-16). 214 217 * 215 218 * @returns Pointer to a SHFLSTRING buffer containing the copy. 216 219 * NULL if out of memory or the string is too long. 217 * @param pachSrc The string to clone. 218 * @param cchSrc The length of the substring, RTMAX_STR for the whole. 219 */ 220 PSHFLSTRING vboxSfOs2StrDup(const char *pachSrc, size_t cchSrc) 221 { 222 if (cchSrc == RTSTR_MAX) 223 cchSrc = strlen(pachSrc); 224 if (cchSrc < 0x1000) 225 { 226 PSHFLSTRING pStr = (PSHFLSTRING)VbglR0PhysHeapAlloc(SHFLSTRING_HEADER_SIZE + cchSrc + 1); 227 if (pStr) 228 { 229 pStr->u16Size = (uint16_t)(cchSrc + 1); 230 pStr->u16Length = (uint16_t)cchSrc; 231 memcpy(pStr->String.ach, pachSrc, cchSrc); 232 pStr->String.ach[cchSrc] = '\0'; 233 return pStr; 234 } 220 * @param pSrc The string to clone. 221 */ 222 PSHFLSTRING vboxSfOs2StrDup(PCSHFLSTRING pSrc) 223 { 224 PSHFLSTRING pDst = (PSHFLSTRING)VbglR0PhysHeapAlloc(SHFLSTRING_HEADER_SIZE + pSrc->u16Length + sizeof(RTUTF16)); 225 if (pDst) 226 { 227 pDst->u16Size = pSrc->u16Length + (uint16_t)sizeof(RTUTF16); 228 pDst->u16Length = pSrc->u16Length; 229 memcpy(&pDst->String, &pSrc->String, pSrc->u16Length); 230 pDst->String.utf16[pSrc->u16Length / sizeof(RTUTF16)] = '\0'; 231 return pDst; 235 232 } 236 233 return NULL; … … 268 265 int rc = VbglR0SfConnect(&g_SfClient); 269 266 if (RT_SUCCESS(rc)) 270 { 271 rc = VbglR0SfSetUtf8(&g_SfClient); 272 if (RT_SUCCESS(rc)) 273 g_fIsConnectedToService = true; 274 else 275 { 276 LogRel(("VbglR0SfSetUtf8 failed: %Rrc\n", rc)); 277 VbglR0SfDisconnect(&g_SfClient); 278 } 279 } 267 g_fIsConnectedToService = true; 280 268 else 281 269 LogRel(("VbglR0SfConnect failed: %Rrc\n", rc)); … … 358 346 * 359 347 * @returns VBox status code. 360 * @param pName The name of the folder to map. 348 * @param pName The name of the folder to map - ASCII (not UTF-16!). 349 * Must be large enough to hold UTF-16 expansion of the 350 * string, will do so upon return. 361 351 * @param pszTag Folder tag (for the VBoxService automounter). Optional. 362 352 * @param ppFolder Where to return the folder structure on success. … … 386 376 memcpy(&pNew->szName[pName->u16Length + 1], pszTag, cbTag); 387 377 378 /* Expand the folder name to UTF-16. */ 379 uint8_t off = pNew->cchName; 380 uint8_t volatile const *pbSrc = &pName->String.utf8[0]; 381 RTUTF16 volatile *pwcDst = &pName->String.utf16[0]; 382 do 383 pwcDst[off] = pbSrc[off]; 384 while (off-- > 0); 385 pName->u16Length *= sizeof(RTUTF16); 386 Assert(pName->u16Length + sizeof(RTUTF16) <= pName->u16Size); 387 388 /* Try do the mapping.*/ 388 389 rc = VbglR0SfMapFolder(&g_SfClient, pName, &pNew->hHostFolder); 389 390 if (RT_SUCCESS(rc)) … … 397 398 else 398 399 { 399 LogRel(("vboxSfOs2MapFolder: VbglR0SfMapFolder(,% .*s,) -> %Rrc\n", pName->u16Length, pName->String.utf8, rc));400 LogRel(("vboxSfOs2MapFolder: VbglR0SfMapFolder(,%s,) -> %Rrc\n", pNew->szName, rc)); 400 401 RTMemFree(pNew); 401 402 } … … 465 466 466 467 /** 467 * Converts a path to UTF- 8and puts it in a VBGL friendly buffer.468 * Converts a path to UTF-16 and puts it in a VBGL friendly buffer. 468 469 * 469 470 * @returns OS/2 status code … … 474 475 APIRET vboxSfOs2ConvertPath(const char *pszFolderPath, PSHFLSTRING *ppStr) 475 476 { 476 /* Skip unnecessary leading slashes. */ 477 /* 478 * Skip unnecessary leading slashes. 479 */ 477 480 char ch = *pszFolderPath; 478 481 if (ch == '\\' || ch == '/') … … 480 483 pszFolderPath++; 481 484 482 /** @todo do proper codepage -> utf8 conversion and straighten out 483 * everything... */ 485 /* 486 * Since the KEE unicode conversion routines does not seem to know of 487 * surrogate pairs, we will get a very good output size estimate by 488 * using strlen() on the input. 489 */ 484 490 size_t cchSrc = strlen(pszFolderPath); 485 PSHFLSTRING pDst = vboxSfOs2StrAlloc(cchSrc );491 PSHFLSTRING pDst = vboxSfOs2StrAlloc(cchSrc + 4 /*fudge*/); 486 492 if (pDst) 487 493 { 488 pDst->u16Length = (uint16_t)cchSrc; 489 memcpy(pDst->String.utf8, pszFolderPath, cchSrc); 490 pDst->String.utf8[cchSrc] = '\0'; 491 *ppStr = pDst; 492 return NO_ERROR; 493 } 494 APIRET rc = KernStrToUcs(NULL, &pDst->String.utf16[0], (char *)pszFolderPath, cchSrc + 4, cchSrc); 495 if (rc == NO_ERROR) 496 { 497 pDst->u16Length = (uint16_t)RTUtf16Len(pDst->String.utf16) * (uint16_t)sizeof(RTUTF16); 498 *ppStr = pDst; 499 return NO_ERROR; 500 } 501 VbglR0PhysHeapFree(pDst); 502 503 /* 504 * This shouldn't happen, but just in case we try again with 505 * twice the buffer size. 506 */ 507 if (rc == 0x20412 /*ULS_BUFFERFULL*/) 508 { 509 pDst = vboxSfOs2StrAlloc((cchSrc + 16) * 2); 510 if (pDst) 511 { 512 rc = KernStrToUcs(NULL, pDst->String.utf16, (char *)pszFolderPath, (cchSrc + 16) * 2, cchSrc); 513 if (rc == NO_ERROR) 514 { 515 pDst->u16Length = (uint16_t)RTUtf16Len(pDst->String.utf16) * (uint16_t)sizeof(RTUTF16); 516 *ppStr = pDst; 517 return NO_ERROR; 518 } 519 VbglR0PhysHeapFree(pDst); 520 LogRel(("vboxSfOs2ConvertPath: KernStrToUcs returns %#x for %.*Rhxs\n", rc, cchSrc, pszFolderPath)); 521 } 522 } 523 else 524 LogRel(("vboxSfOs2ConvertPath: KernStrToUcs returns %#x for %.*Rhxs\n", rc, cchSrc, pszFolderPath)); 525 } 526 527 LogRel(("vboxSfOs2ConvertPath: Out of memory - cchSrc=%#x\n", cchSrc)); 494 528 *ppStr = NULL; 529 return ERROR_NOT_ENOUGH_MEMORY; 530 } 531 532 533 /** 534 * Converts a path to UTF-16 and puts it in a VBGL friendly buffer within a 535 * larger buffer. 536 * 537 * @returns OS/2 status code 538 * @param pszFolderPath The path to convert. 539 * @param offStrInBuf The offset of the SHLFSTRING in the return buffer. 540 * This first part of the buffer is zeroed. 541 * @param ppvBuf Where to return the pointer to the buffer. Free 542 * using vboxSfOs2FreePath. 543 */ 544 APIRET vboxSfOs2ConvertPathEx(const char *pszFolderPath, uint32_t offStrInBuf, void **ppvBuf) 545 { 546 /* 547 * Skip unnecessary leading slashes. 548 */ 549 char ch = *pszFolderPath; 550 if (ch == '\\' || ch == '/') 551 while ((ch = pszFolderPath[1]) == '\\' || ch == '/') 552 pszFolderPath++; 553 554 /* 555 * Since the KEE unicode conversion routines does not seem to know of 556 * surrogate pairs, we will get a very good output size estimate by 557 * using strlen() on the input. 558 */ 559 size_t cchSrc = strlen(pszFolderPath); 560 void *pvBuf = VbglR0PhysHeapAlloc(offStrInBuf + SHFLSTRING_HEADER_SIZE + (cchSrc + 4) * sizeof(RTUTF16)); 561 if (pvBuf) 562 { 563 RT_BZERO(pvBuf, offStrInBuf); 564 565 PSHFLSTRING pDst = (PSHFLSTRING)((uint8_t *)pvBuf + offStrInBuf); 566 APIRET rc = KernStrToUcs(NULL, &pDst->String.utf16[0], (char *)pszFolderPath, cchSrc + 4, cchSrc); 567 if (rc == NO_ERROR) 568 { 569 pDst->u16Length = (uint16_t)RTUtf16Len(pDst->String.utf16) * (uint16_t)sizeof(RTUTF16); 570 pDst->u16Size = (uint16_t)((cchSrc + 4) * sizeof(RTUTF16)); 571 Assert(pDst->u16Length < pDst->u16Size); 572 *ppvBuf = pvBuf; 573 return NO_ERROR; 574 } 575 VbglR0PhysHeapFree(pvBuf); 576 577 #if 0 578 /* 579 * This shouldn't happen, but just in case we try again with 580 * twice the buffer size. 581 */ 582 if (rc == 0x20412 /*ULS_BUFFERFULL*/) 583 { 584 pDst = vboxSfOs2StrAlloc((cchSrc + 16) * 2); 585 if (pDst) 586 { 587 rc = KernStrToUcs(NULL, pDst->String.utf16, (char *)pszFolderPath, (cchSrc + 16) * 2, cchSrc); 588 if (rc == NO_ERROR) 589 { 590 pDst->u16Length = (uint16_t)RTUtf16Len(pDst->String.utf16) * (uint16_t)sizeof(RTUTF16); 591 *ppStr = pDst; 592 return NO_ERROR; 593 } 594 VbglR0PhysHeapFree(pDst); 595 LogRel(("vboxSfOs2ConvertPath: KernStrToUcs returns %#x for %.*Rhxs\n", rc, cchSrc, pszFolderPath)); 596 } 597 } 598 else 599 #endif 600 LogRel(("vboxSfOs2ConvertPath: KernStrToUcs returns %#x for %.*Rhxs\n", rc, cchSrc, pszFolderPath)); 601 } 602 603 LogRel(("vboxSfOs2ConvertPath: Out of memory - cchSrc=%#x offStrInBuf=%#x\n", cchSrc, offStrInBuf)); 604 *ppvBuf = NULL; 495 605 return ERROR_NOT_ENOUGH_MEMORY; 496 606 } … … 553 663 * Copy the name into the buffer format that Vbgl desires. 554 664 */ 555 PSHFLSTRING pStrName = vboxSfOs2Str Dup(pachFolderName,cchFolderName);665 PSHFLSTRING pStrName = vboxSfOs2StrAlloc(cchFolderName); 556 666 if (pStrName) 557 667 { 668 memcpy(pStrName->String.ach, pachFolderName, cchFolderName); 669 pStrName->String.ach[cchFolderName] = '\0'; 670 pStrName->u16Length = (uint16_t)cchFolderName; 671 558 672 /* 559 673 * Do the attaching. … … 692 806 */ 693 807 rc = vboxSfOs2ConvertPath(&pszPath[3], ppStrFolderPath); 808 if (rc == NO_ERROR) 809 return rc; 810 811 vboxSfOs2ReleaseFolder(pFolder); 812 *ppFolder = NULL; 813 return rc; 814 } 815 KernReleaseSharedMutex(&g_MtxFolders); 816 LogRel(("vboxSfOs2ResolvePath: No folder mapped on '%s'. Detach race?\n", pszPath)); 817 return ERROR_PATH_NOT_FOUND; 818 } 819 LogRel(("vboxSfOs2ResolvePath: No root slash: '%s'\n", pszPath)); 820 return ERROR_PATH_NOT_FOUND; 821 } 822 LogRel(("vboxSfOs2ResolvePath: Unexpected path: %s\n", pszPath)); 823 RT_NOREF_PV(pCdFsd); RT_NOREF_PV(offCurDirEnd); 824 return ERROR_PATH_NOT_FOUND; 825 } 826 827 828 /** 829 * Resolves the given path to a folder structure and folder relative string, 830 * the latter placed within a larger request buffer. 831 * 832 * @returns OS/2 status code. 833 * @param pszPath The path to resolve. 834 * @param pCdFsd The IFS dependent CWD structure if present. 835 * @param offCurDirEnd The offset into @a pszPath of the CWD. -1 if not 836 * CWD relative path. 837 * @param offStrInBuf The offset of the SHLFSTRING in the return buffer. 838 * This first part of the buffer is zeroed. 839 * @param ppFolder Where to return the referenced pointer to the folder 840 * structure. Call vboxSfOs2ReleaseFolder() when done. 841 * @param ppvBuf Where to return the Pointer to the buffer. Free 842 * using VbglR0PhysHeapFree. 843 */ 844 APIRET vboxSfOs2ResolvePathEx(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd, uint32_t offStrInBuf, 845 PVBOXSFFOLDER *ppFolder, void **ppvBuf) 846 { 847 APIRET rc; 848 849 /* 850 * UNC path? Reject the prefix to be on the safe side. 851 */ 852 char ch = pszPath[0]; 853 if (ch == '\\' || ch == '/') 854 { 855 size_t cchPrefix = vboxSfOs2UncPrefixLength(pszPath); 856 if (cchPrefix > 0) 857 { 858 /* Find the length of the folder name (share). */ 859 const char *pszFolderName = &pszPath[cchPrefix]; 860 size_t cchFolderName = 0; 861 while ((ch = pszFolderName[cchFolderName]) != '\0' && ch != '\\' && ch != '/') 862 { 863 if ((uint8_t)ch >= 0x20 && (uint8_t)ch <= 0x7f && ch != ':') 864 cchFolderName++; 865 else 866 { 867 LogRel(("vboxSfOs2ResolvePath: Invalid share name (@%u): %.*Rhxs\n", 868 cchPrefix + cchFolderName, strlen(pszPath), pszPath)); 869 return ERROR_INVALID_NAME; 870 } 871 } 872 if (cchFolderName >= VBOXSFOS2_MAX_FOLDER_NAME) 873 { 874 LogRel(("vboxSfOs2ResolvePath: Folder name is too long: %u, max %u (%s)\n", 875 cchFolderName, VBOXSFOS2_MAX_FOLDER_NAME, pszPath)); 876 return ERROR_FILENAME_EXCED_RANGE; 877 } 878 879 /* 880 * Look for the share. 881 */ 882 KernRequestSharedMutex(&g_MtxFolders); 883 PVBOXSFFOLDER pFolder = *ppFolder = vboxSfOs2FindAndRetainFolder(pszFolderName, cchFolderName); 884 if (pFolder) 885 { 886 vboxSfOs2RetainFolder(pFolder); 887 KernReleaseSharedMutex(&g_MtxFolders); 888 } 889 else 890 { 891 uint32_t const uRevBefore = g_uFolderRevision; 892 KernReleaseSharedMutex(&g_MtxFolders); 893 rc = vboxSfOs2AttachUncAndRetain(pszFolderName, cchFolderName, uRevBefore, ppFolder); 894 if (rc == NO_ERROR) 895 pFolder = *ppFolder; 896 else 897 return rc; 898 } 899 900 /* 901 * Convert the path and put it in a Vbgl compatible buffer.. 902 */ 903 rc = vboxSfOs2ConvertPathEx(&pszFolderName[cchFolderName], offStrInBuf, ppvBuf); 904 if (rc == NO_ERROR) 905 return rc; 906 907 vboxSfOs2ReleaseFolder(pFolder); 908 *ppFolder = NULL; 909 return rc; 910 } 911 912 LogRel(("vboxSfOs2ResolvePath: Unexpected path: %s\n", pszPath)); 913 return ERROR_PATH_NOT_FOUND; 914 } 915 916 /* 917 * Drive letter? 918 */ 919 ch &= ~0x20; /* upper case */ 920 if ( ch >= 'A' 921 && ch <= 'Z' 922 && pszPath[1] == ':') 923 { 924 unsigned iDrive = ch - 'A'; 925 ch = pszPath[2]; 926 if (ch == '\\' || ch == '/') 927 { 928 KernRequestSharedMutex(&g_MtxFolders); 929 PVBOXSFFOLDER pFolder = *ppFolder = g_apDriveFolders[iDrive]; 930 if (pFolder) 931 { 932 vboxSfOs2RetainFolder(pFolder); 933 KernReleaseSharedMutex(&g_MtxFolders); 934 935 /* 936 * Convert the path and put it in a Vbgl compatible buffer.. 937 */ 938 rc = vboxSfOs2ConvertPathEx(&pszPath[3], offStrInBuf, ppvBuf); 694 939 if (rc == NO_ERROR) 695 940 return rc; … … 1006 1251 RT_NOREF(uType); /* pass 1 or pass 2 doesn't matter to us, we've only got one 'server'. */ 1007 1252 1008 if (vboxSfOs2UncPrefixLength(pszName) > 0 1253 if (vboxSfOs2UncPrefixLength(pszName) > 0) 1009 1254 return NO_ERROR; 1010 1255 return ERROR_NOT_SUPPORTED; … … 1074 1319 { 1075 1320 SHFLSTRING Path; 1076 uint8_t abPadding[SHFLSTRING_HEADER_SIZE + 4 ];1321 uint8_t abPadding[SHFLSTRING_HEADER_SIZE + 4 * sizeof(RTUTF16)]; 1077 1322 }; 1078 1323 } Open; … … 1096 1341 pu->Open.Params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACT_OPEN_IF_EXISTS 1097 1342 | SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ | SHFL_CF_ACCESS_DENYNONE; 1098 pu->Open.Path.u16Size = 3 ;1099 pu->Open.Path.u16Length = 2 ;1100 pu->Open.Path.String.utf 8[0] = '\\';1101 pu->Open.Path.String.utf 8[1] = '.';1102 pu->Open.Path.String.utf 8[2] = '\0';1343 pu->Open.Path.u16Size = 3 * sizeof(RTUTF16); 1344 pu->Open.Path.u16Length = 2 * sizeof(RTUTF16); 1345 pu->Open.Path.String.utf16[0] = '\\'; 1346 pu->Open.Path.String.utf16[1] = '.'; 1347 pu->Open.Path.String.utf16[2] = '\0'; 1103 1348 1104 1349 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, &pu->Open.Path, &pu->Open.Params); … … 1272 1517 { 1273 1518 LogFlow(("FS32_MKDIR: pCdFsi=%p pCdFsd=%p pszDir=%p:{%s} pEAOp=%p fFlags=%#x\n", pCdFsi, pCdFsd, pszDir, pszDir, offCurDirEnd, pEaOp, fFlags)); 1519 RT_NOREF(fFlags); 1274 1520 1275 1521 /* … … 1626 1872 LogFlow(("FS32_FILEATTRIBUTE: fFlags=%#x pCdFsi=%p:{%#x,%s} pCdFsd=%p pszName=%p:{%s} offCurDirEnd=%d pfAttr=%p\n", 1627 1873 fFlags, pCdFsi, pCdFsi->cdi_hVPB, pCdFsi->cdi_curdir, pCdFsd, pszName, pszName, offCurDirEnd, pfAttr)); 1628 RT_NOREF( offCurDirEnd);1874 RT_NOREF(pCdFsi, offCurDirEnd); 1629 1875 1630 1876 APIRET rc; -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFFile.cpp
r75650 r76108 50 50 LogFlow(("FS32_OPENCREATE: pCdFsi=%p pCdFsd=%p pszName=%p:{%s} offCurDirEnd=%d pSfFsi=%p pSfFsd=%p fOpenMode=%#x fOpenFlags=%#x puAction=%p fAttribs=%#x pbEaBuf=%p pfGenFlag=%p\n", 51 51 pCdFsi, pCdFsd, pszName, pszName, offCurDirEnd, pSfFsi, pSfFsd, fOpenMode, fOpenFlags, puAction, fAttribs, pbEaBuf, pfGenFlag)); 52 RT_NOREF(pfGenFlag );52 RT_NOREF(pfGenFlag, pCdFsi); 53 53 54 54 /* … … 73 73 } 74 74 75 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 76 if (!pParams) 77 return ERROR_NOT_ENOUGH_MEMORY; 78 RT_ZERO(*pParams); 79 75 /* 76 * Allocate request buffer and resovle the path to folder and folder relative path. 77 */ 78 PVBOXSFFOLDER pFolder; 79 VBOXSFCREATEREQ *pReq; 80 APIRET rc = vboxSfOs2ResolvePathEx(pszName, pCdFsd, offCurDirEnd, RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath), 81 &pFolder, (void **)&pReq); 82 LogFlow(("FS32_OPENCREATE: vboxSfOs2ResolvePath: -> %u pFolder=%p\n", rc, pFolder)); 83 if (rc == NO_ERROR) 84 { /* likely */ } 85 else 86 return rc; 87 88 /* 89 * Continue validating and converting parameters. 90 */ 80 91 /* access: */ 81 92 if (fOpenMode & OPEN_ACCESS_READWRITE) 82 p Params->CreateFlags = SHFL_CF_ACCESS_READWRITE | SHFL_CF_ACCESS_ATTR_READWRITE;93 pReq->CreateParms.CreateFlags = SHFL_CF_ACCESS_READWRITE | SHFL_CF_ACCESS_ATTR_READWRITE; 83 94 else if (fOpenMode & OPEN_ACCESS_WRITEONLY) 84 p Params->CreateFlags = SHFL_CF_ACCESS_WRITE | SHFL_CF_ACCESS_ATTR_WRITE;95 pReq->CreateParms.CreateFlags = SHFL_CF_ACCESS_WRITE | SHFL_CF_ACCESS_ATTR_WRITE; 85 96 else 86 p Params->CreateFlags = SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ; /* read or/and exec */97 pReq->CreateParms.CreateFlags = SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ; /* read or/and exec */ 87 98 88 99 /* Sharing: */ 89 100 switch (fOpenMode & (OPEN_SHARE_DENYNONE | OPEN_SHARE_DENYREADWRITE | OPEN_SHARE_DENYREAD | OPEN_SHARE_DENYWRITE)) 90 101 { 91 case OPEN_SHARE_DENYNONE: p Params->CreateFlags |= SHFL_CF_ACCESS_DENYNONE; break;92 case OPEN_SHARE_DENYWRITE: p Params->CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; break;93 case OPEN_SHARE_DENYREAD: p Params->CreateFlags |= SHFL_CF_ACCESS_DENYREAD; break;94 case OPEN_SHARE_DENYREADWRITE: p Params->CreateFlags |= SHFL_CF_ACCESS_DENYALL; break;95 case 0: p Params->CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; break; /* compatibility */102 case OPEN_SHARE_DENYNONE: pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYNONE; break; 103 case OPEN_SHARE_DENYWRITE: pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; break; 104 case OPEN_SHARE_DENYREAD: pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYREAD; break; 105 case OPEN_SHARE_DENYREADWRITE: pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYALL; break; 106 case 0: pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; break; /* compatibility */ 96 107 default: 97 108 LogRel(("FS32_OPENCREATE: Invalid file sharing mode: %#x\n", fOpenMode)); 98 VbglR0PhysHeapFree(p Params);109 VbglR0PhysHeapFree(pReq); 99 110 return VERR_INVALID_PARAMETER; 100 111 … … 104 115 switch (fOpenFlags & 0x13) 105 116 { 106 case OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x00 */107 p Params->CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW;117 case OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x00 */ 118 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; 108 119 break; 109 case OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x10 */110 p Params->CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;120 case OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x10 */ 121 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; 111 122 break; 112 case OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x01 */113 p Params->CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW;123 case OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x01 */ 124 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; 114 125 break; 115 case OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x11 */116 p Params->CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;126 case OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x11 */ 127 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; 117 128 break; 118 case OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x02 */119 p Params->CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW;129 case OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x02 */ 130 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; 120 131 break; 121 case OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x12 */122 p Params->CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;132 case OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x12 */ 133 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; 123 134 break; 124 135 default: 125 136 LogRel(("FS32_OPENCREATE: Invalid file open flags: %#x\n", fOpenFlags)); 126 VbglR0PhysHeapFree(p Params);137 VbglR0PhysHeapFree(pReq); 127 138 return VERR_INVALID_PARAMETER; 128 139 } … … 131 142 132 143 /* Attributes: */ 133 p Params->Info.Attr.fMode = ((uint32_t)fAttribs << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_OS2;144 pReq->CreateParms.Info.Attr.fMode = ((uint32_t)fAttribs << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_OS2; 134 145 135 146 /* Initial size: */ 136 147 if (pSfFsi->sfi_sizel > 0) 137 pParams->Info.cbObject = pSfFsi->sfi_sizel; 138 139 /* 140 * Resolve path to a folder and folder relative path. 141 */ 142 PVBOXSFFOLDER pFolder; 143 PSHFLSTRING pStrFolderPath; 144 RT_NOREF(pCdFsi); 145 APIRET rc = vboxSfOs2ResolvePath(pszName, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 146 LogFlow(("FS32_OPENCREATE: vboxSfOs2ResolvePath: -> %u pFolder=%p\n", rc, pFolder)); 147 if (rc == NO_ERROR) 148 { 149 /* 150 * Try open the file. 151 */ 152 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 153 LogFlow(("FS32_OPENCREATE: VbglR0SfCreate -> %Rrc Result=%d fMode=%#x\n", vrc, pParams->Result, pParams->Info.Attr.fMode)); 154 if (RT_SUCCESS(vrc)) 148 pReq->CreateParms.Info.cbObject = pSfFsi->sfi_sizel; 149 150 /* 151 * Try open the file. 152 */ 153 int vrc = vboxSfOs2HostReqCreate(pFolder, pReq); 154 LogFlow(("FS32_OPENCREATE: VbglR0SfCreate -> %Rrc Result=%d fMode=%#x\n", vrc, pReq->CreateParms.Result, pReq->CreateParms.Info.Attr.fMode)); 155 if (RT_SUCCESS(vrc)) 156 { 157 switch (pReq->CreateParms.Result) 155 158 { 156 switch (pParams->Result) 157 { 158 case SHFL_FILE_EXISTS: 159 if (pParams->Handle == SHFL_HANDLE_NIL) 160 { 161 rc = ERROR_OPEN_FAILED; //ERROR_FILE_EXISTS; 162 break; 163 } 164 RT_FALL_THRU(); 165 case SHFL_FILE_CREATED: 166 case SHFL_FILE_REPLACED: 167 if ( pParams->Info.cbObject < _2G 168 || (fOpenMode & OPEN_FLAGS_LARGEFILE)) 169 { 170 pSfFsd->u32Magic = VBOXSFSYFI_MAGIC; 171 pSfFsd->pSelf = pSfFsd; 172 pSfFsd->hHostFile = pParams->Handle; 173 pSfFsd->pFolder = pFolder; 174 175 uint32_t cOpenFiles = ASMAtomicIncU32(&pFolder->cOpenFiles); 176 Assert(cOpenFiles < _32K); 177 pFolder = NULL; /* Reference now taken by pSfFsd->pFolder. */ 178 179 pSfFsi->sfi_sizel = pParams->Info.cbObject; 180 pSfFsi->sfi_type = STYPE_FILE; 181 pSfFsi->sfi_DOSattr = (uint8_t)((pParams->Info.Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT); 182 int16_t cMinLocalTimeDelta = vboxSfOs2GetLocalTimeDelta(); 183 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_cdate, &pSfFsi->sfi_ctime, pParams->Info.BirthTime, cMinLocalTimeDelta); 184 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_adate, &pSfFsi->sfi_atime, pParams->Info.AccessTime, cMinLocalTimeDelta); 185 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_mdate, &pSfFsi->sfi_mtime, pParams->Info.ModificationTime, cMinLocalTimeDelta); 186 if (pParams->Result == SHFL_FILE_CREATED) 187 pSfFsi->sfi_tstamp |= ST_PCREAT | ST_SCREAT | ST_PWRITE | ST_SWRITE | ST_PREAD | ST_SREAD; 188 189 *puAction = pParams->Result == SHFL_FILE_CREATED ? FILE_CREATED 190 : pParams->Result == SHFL_FILE_EXISTS ? FILE_EXISTED 191 : FILE_TRUNCATED; 192 193 Log(("FS32_OPENCREATE: hHandle=%#RX64 for '%s'\n", pSfFsd->hHostFile, pszName)); 194 rc = NO_ERROR; 195 } 196 else 197 { 198 LogRel(("FS32_OPENCREATE: cbObject=%#RX64 no OPEN_FLAGS_LARGEFILE (%s)\n", pParams->Info.cbObject, pszName)); 199 VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pParams->Handle); 200 rc = ERROR_ACCESS_DENIED; 201 } 159 case SHFL_FILE_EXISTS: 160 if (pReq->CreateParms.Handle == SHFL_HANDLE_NIL) 161 { 162 rc = ERROR_OPEN_FAILED; //ERROR_FILE_EXISTS; 202 163 break; 203 204 case SHFL_PATH_NOT_FOUND: 205 rc = ERROR_PATH_NOT_FOUND; 206 break; 207 208 default: 209 case SHFL_FILE_NOT_FOUND: 210 rc = ERROR_OPEN_FAILED; 211 break; 212 } 164 } 165 RT_FALL_THRU(); 166 case SHFL_FILE_CREATED: 167 case SHFL_FILE_REPLACED: 168 if ( pReq->CreateParms.Info.cbObject < _2G 169 || (fOpenMode & OPEN_FLAGS_LARGEFILE)) 170 { 171 pSfFsd->u32Magic = VBOXSFSYFI_MAGIC; 172 pSfFsd->pSelf = pSfFsd; 173 pSfFsd->hHostFile = pReq->CreateParms.Handle; 174 pSfFsd->pFolder = pFolder; 175 176 uint32_t cOpenFiles = ASMAtomicIncU32(&pFolder->cOpenFiles); 177 Assert(cOpenFiles < _32K); 178 pFolder = NULL; /* Reference now taken by pSfFsd->pFolder. */ 179 180 pSfFsi->sfi_sizel = pReq->CreateParms.Info.cbObject; 181 pSfFsi->sfi_type = STYPE_FILE; 182 pSfFsi->sfi_DOSattr = (uint8_t)((pReq->CreateParms.Info.Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT); 183 int16_t cMinLocalTimeDelta = vboxSfOs2GetLocalTimeDelta(); 184 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_cdate, &pSfFsi->sfi_ctime, pReq->CreateParms.Info.BirthTime, cMinLocalTimeDelta); 185 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_adate, &pSfFsi->sfi_atime, pReq->CreateParms.Info.AccessTime, cMinLocalTimeDelta); 186 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_mdate, &pSfFsi->sfi_mtime, pReq->CreateParms.Info.ModificationTime, cMinLocalTimeDelta); 187 if (pReq->CreateParms.Result == SHFL_FILE_CREATED) 188 pSfFsi->sfi_tstamp |= ST_PCREAT | ST_SCREAT | ST_PWRITE | ST_SWRITE | ST_PREAD | ST_SREAD; 189 190 *puAction = pReq->CreateParms.Result == SHFL_FILE_CREATED ? FILE_CREATED 191 : pReq->CreateParms.Result == SHFL_FILE_EXISTS ? FILE_EXISTED 192 : FILE_TRUNCATED; 193 194 Log(("FS32_OPENCREATE: hHandle=%#RX64 for '%s'\n", pSfFsd->hHostFile, pszName)); 195 rc = NO_ERROR; 196 } 197 else 198 { 199 LogRel(("FS32_OPENCREATE: cbObject=%#RX64 no OPEN_FLAGS_LARGEFILE (%s)\n", pReq->CreateParms.Info.cbObject, pszName)); 200 VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pReq->CreateParms.Handle); 201 rc = ERROR_ACCESS_DENIED; 202 } 203 break; 204 205 case SHFL_PATH_NOT_FOUND: 206 rc = ERROR_PATH_NOT_FOUND; 207 break; 208 209 default: 210 case SHFL_FILE_NOT_FOUND: 211 rc = ERROR_OPEN_FAILED; 212 break; 213 213 } 214 else if (vrc == VERR_ALREADY_EXISTS)215 rc = ERROR_ACCESS_DENIED;216 else if (vrc == VERR_FILE_NOT_FOUND)217 rc = ERROR_OPEN_FAILED;218 else219 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_PATH_NOT_FOUND);220 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder);221 }222 VbglR0PhysHeapFree(pParams);214 } 215 else if (vrc == VERR_ALREADY_EXISTS) 216 rc = ERROR_ACCESS_DENIED; 217 else if (vrc == VERR_FILE_NOT_FOUND) 218 rc = ERROR_OPEN_FAILED; 219 else 220 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_PATH_NOT_FOUND); 221 VbglR0PhysHeapFree(pReq); 222 vboxSfOs2ReleaseFolder(pFolder); 223 223 LogFlow(("FS32_OPENCREATE: returns %u\n", rc)); 224 224 return rc; … … 465 465 return rc; 466 466 } 467 468 #include <VBox/VBoxGuest.h>469 470 467 471 468 -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFFind.cpp
r75461 r76108 49 49 * 50 50 * @returns true if compatible, false if not. 51 * @param p szName The name to inspect (UTF-8).52 * @param c chName The length of the name.53 * @param p wszTmpBuffer for test conversions.54 * @param c wcTmpThe size of the buffer.51 * @param pwszName The name to inspect (UTF-16). 52 * @param cwcName The length of the name. 53 * @param pszTmp Buffer for test conversions. 54 * @param cbTmp The size of the buffer. 55 55 */ 56 static bool vboxSfOs2IsUtf 8Name8dot3(const char *pszName, size_t cchName, PRTUTF16 pwszTmp, size_t cwcTmp)57 { 58 /* Reject names that must be too long when using maximum UTF-8 encoding. */59 if (c chName > (8 + 1 + 3) * 4)56 static bool vboxSfOs2IsUtf16Name8dot3(PRTUTF16 pwszName, size_t cwcName, char *pszTmp, size_t cbTmp) 57 { 58 /* Reject names that must be too long. */ 59 if (cwcName > 8 + 1 + 3) 60 60 return false; 61 61 62 /* First char cannot be a dot . */63 if (*p szName == '.' || !*pszName)62 /* First char cannot be a dot, nor can it be an empty string. */ 63 if (*pwszName == '.' || !*pwszName) 64 64 return false; 65 65 … … 67 67 * To basic checks on code point level before doing full conversion. 68 68 */ 69 const char *pszCursor = pszName; 70 for (uint32_t cuc = 0; ; cuc++) 71 { 72 RTUNICP uCp; 73 RTStrGetCpEx(&pszCursor, &uCp); 74 if (uCp == '.') 69 for (unsigned off = 0; ; off++) 70 { 71 RTUTF16 wc = pwszName[off]; 72 if (wc == '.') 75 73 { 76 for (cuc = 0; ; cuc++) 77 { 78 RTStrGetCpEx(&pszCursor, &uCp); 79 if (!uCp) 74 unsigned const offMax = off + 3; 75 for (++off;; off++) 76 { 77 wc = pwszName[off]; 78 if (!wc) 80 79 break; 81 if ( uCp== '.')80 if (wc == '.') 82 81 return false; 83 if ( cuc >= 3)82 if (off >= offMax) 84 83 return false; 85 84 } 86 85 break; 87 86 } 88 if (! uCp)87 if (!wc) 89 88 break; 90 if ( cuc>= 8)89 if (off >= 8) 91 90 return false; 92 91 } 93 92 94 93 /* 95 * Convert to UTF-16 and then to native codepage. 96 */ 97 size_t cwcActual = cwcTmp; 98 int rc = RTStrToUtf16Ex(pszName, cchName, &pwszTmp, cwcTmp, &cwcActual); 99 if (RT_SUCCESS(rc)) 100 { 101 char *pszTmp = (char *)&pwszTmp[cwcActual + 1]; 102 rc = KernStrFromUcs(NULL, pszTmp, pwszTmp, (cwcTmp - cwcActual - 1) * sizeof(RTUTF16), cwcActual); 103 if (rc != NO_ERROR) 104 { 105 LogRel(("vboxSfOs2IsUtf8Name8dot3: KernStrFromUcs failed: %d\n", rc)); 94 * Conver to the native code page. 95 */ 96 APIRET rc = KernStrFromUcs(NULL, pszTmp, pwszName, cbTmp, cwcName); 97 if (rc != NO_ERROR) 98 { 99 LogRel(("vboxSfOs2IsUtf8Name8dot3: KernStrFromUcs failed: %d\n", rc)); 100 return false; 101 } 102 103 /* 104 * Redo the check. 105 * Note! This could be bogus if a DBCS leadin sequence collides with '.'. 106 */ 107 for (unsigned cch = 0; ; cch++) 108 { 109 char ch = *pszTmp++; 110 if (ch == '.') 111 break; 112 if (ch == '\0') 113 return true; 114 if (cch >= 8) 106 115 return false; 107 } 108 109 /* 110 * Redo the check. 111 * Note! This could be bogus if a DBCS leadin sequence collides with '.'. 112 */ 113 for (uint32_t cch = 0; ; cch++) 114 { 115 char ch = *pszTmp++; 116 if (ch == '.') 117 break; 118 if (ch == '\0') 119 return true; 120 if (cch >= 8) 121 return false; 122 } 123 for (uint32_t cch = 0; ; cch++) 124 { 125 char ch = *pszTmp++; 126 if (ch == '\0') 127 return true; 128 if (ch != '.') 129 return false; 130 if (cch >= 3) 131 return false; 132 } 133 } 134 else 135 LogRel(("vboxSfOs2IsUtf8Name8dot3: RTStrToUtf16Ex failed: %Rrc\n", rc)); 136 return false; 116 } 117 for (unsigned cch = 0; ; cch++) 118 { 119 char ch = *pszTmp++; 120 if (ch == '\0') 121 return true; 122 if (ch != '.') 123 return false; 124 if (cch >= 3) 125 return false; 126 } 137 127 } 138 128 … … 141 131 * @returns Updated pbDst on success, NULL on failure. 142 132 */ 143 static uint8_t *vboxSfOs2CopyUtf8Name(uint8_t *pbDst, PRTUTF16 pwszTmp, size_t cwcTmp, const char *pszSrc, size_t cchSrc) 144 { 145 /* Convert UTF-8 to UTF-16: */ 146 int rc = RTStrToUtf16Ex(pszSrc, cchSrc, &pwszTmp, cwcTmp, &cwcTmp); 147 if (RT_SUCCESS(rc)) 148 { 149 char *pszDst = (char *)(pbDst + 1); 150 rc = KernStrFromUcs(NULL, pszDst, pwszTmp, CCHMAXPATHCOMP, cwcTmp); 151 if (rc == NO_ERROR) 152 { 153 size_t cchDst = strlen(pszDst); 154 *pbDst++ = (uint8_t)cchDst; 155 pbDst += cchDst; 156 *pbDst++ = '\0'; 157 return pbDst; 158 } 159 LogRel(("vboxSfOs2CopyUtf8Name: KernStrFromUcs failed: %d\n", rc)); 160 } 161 else 162 LogRel(("vboxSfOs2CopyUtf8Name: RTStrToUtf16Ex failed: %Rrc\n", rc)); 163 return NULL; 164 } 165 166 167 /** 168 * @returns Updated pbDst on success, NULL on failure. 169 */ 170 static uint8_t *vboxSfOs2CopyUtf8NameAndUpperCase(uint8_t *pbDst, PRTUTF16 pwszTmp, size_t cwcTmp, const char *pszSrc, size_t cchSrc) 171 { 172 /* Convert UTF-8 to UTF-16: */ 173 int rc = RTStrToUtf16Ex(pszSrc, cchSrc, &pwszTmp, cwcTmp, &cwcTmp); 174 if (RT_SUCCESS(rc)) 175 { 176 char *pszDst = (char *)(pbDst + 1); 177 rc = KernStrFromUcs(NULL, pszDst, RTUtf16ToUpper(pwszTmp), CCHMAXPATHCOMP, cwcTmp); 178 if (rc == NO_ERROR) 179 { 180 size_t cchDst = strlen(pszDst); 181 *pbDst++ = (uint8_t)cchDst; 182 pbDst += cchDst; 183 *pbDst++ = '\0'; 184 return pbDst; 185 } 186 LogRel(("vboxSfOs2CopyUtf8NameAndUpperCase: KernStrFromUcs failed: %d\n", rc)); 187 } 188 else 189 LogRel(("vboxSfOs2CopyUtf8NameAndUpperCase: RTStrToUtf16Ex failed: %Rrc\n", rc)); 133 static uint8_t *vboxSfOs2CopyUtf16Name(uint8_t *pbDst, PRTUTF16 pwszSrc, size_t cwcSrc) 134 { 135 char *pszDst = (char *)pbDst + 1; 136 APIRET rc = KernStrFromUcs(NULL, pszDst, pwszSrc, CCHMAXPATHCOMP, cwcSrc); 137 if (rc == NO_ERROR) 138 { 139 size_t cchDst = strlen(pszDst); 140 *pbDst++ = (uint8_t)cchDst; 141 pbDst += cchDst; 142 *pbDst++ = '\0'; 143 return pbDst; 144 } 145 LogRel(("vboxSfOs2CopyUtf8Name: KernStrFromUcs failed: %d\n", rc)); 190 146 return NULL; 191 147 } … … 314 270 && ( pDataBuf->fLongFilenames 315 271 || pEntry->cucShortName 316 || vboxSfOs2IsUtf 8Name8dot3((char *)pEntry->name.String.utf8, pEntry->name.u16Length,317 pDataBuf->wszTmp, sizeof(pDataBuf->wszTmp))))272 || vboxSfOs2IsUtf16Name8dot3(pEntry->name.String.utf16, pEntry->name.u16Length / sizeof(RTUTF16), 273 (char *)pDataBuf->abStaging, sizeof(pDataBuf->abStaging)))) 318 274 { 319 275 /* … … 402 358 /* The length prefixed filename. */ 403 359 if (pDataBuf->fLongFilenames) 404 pbDst = vboxSfOs2CopyUtf8Name(pbDst, pDataBuf->wszTmp, sizeof(pDataBuf->wszTmp), 405 (char *)pEntry->name.String.utf8, pEntry->name.u16Length); 360 pbDst = vboxSfOs2CopyUtf16Name(pbDst, pEntry->name.String.utf16, pEntry->name.u16Length / sizeof(RTUTF16)); 406 361 else if (pEntry->cucShortName == 0) 407 pbDst = vboxSfOs2CopyUtf8NameAndUpperCase(pbDst, pDataBuf->wszTmp, sizeof(pDataBuf->wszTmp), 408 (char *)pEntry->name.String.utf8, pEntry->name.u16Length); 362 pbDst = vboxSfOs2CopyUtf16NameAndUpperCase(pbDst, pEntry->name.String.utf16, pEntry->name.u16Length / sizeof(RTUTF16)); 409 363 else 410 364 pbDst = vboxSfOs2CopyUtf16NameAndUpperCase(pbDst, pEntry->uszShortName, pEntry->cucShortName); … … 520 474 if (rc == NO_ERROR) 521 475 { 476 LogRel(("pStrFolderPath: %#x %#x '%ls'\n", pStrFolderPath->u16Size, pStrFolderPath->u16Length, pStrFolderPath->String.ucs2)); 522 477 /* 523 478 * Look for a wildcard filter at the end of the path, saving it all for … … 525 480 */ 526 481 PSHFLSTRING pFilter = NULL; 527 char *pszFilter = RTPathFilename((char *)pStrFolderPath->String.utf8);528 if ( p szFilter529 && ( strchr(pszFilter, '*') != NULL530 || strchr(pszFilter, '?') != NULL))482 PRTUTF16 pwszFilter = RTPathFilenameUtf16(pStrFolderPath->String.utf16); 483 if ( pwszFilter 484 && ( RTUtf16Chr(pwszFilter, '*') != NULL 485 || RTUtf16Chr(pwszFilter, '?') != NULL)) 531 486 { 532 if ( strcmp(pszFilter, "*.*") == 0)487 if (RTUtf16CmpAscii(pwszFilter, "*.*") == 0) 533 488 { 534 489 /* All files, no filtering needed. Just drop the filter expression from the directory path. */ 535 *p szFilter = '\0';536 pStrFolderPath->u16Length = (uint16_t)((uint8_t *)p szFilter - &pStrFolderPath->String.utf8[0]);490 *pwszFilter = '\0'; 491 pStrFolderPath->u16Length = (uint16_t)((uint8_t *)pwszFilter - &pStrFolderPath->String.utf8[0]); 537 492 } 538 493 else 539 494 { 540 495 /* Duplicate the whole path. */ 541 pFilter = vboxSfOs2StrDup(pStrFolderPath ->String.ach, pStrFolderPath->u16Length);496 pFilter = vboxSfOs2StrDup(pStrFolderPath); 542 497 if (pFilter) 543 498 { 544 499 /* Drop filter from directory path. */ 545 *p szFilter = '\0';546 pStrFolderPath->u16Length = (uint16_t)((uint8_t *)p szFilter - &pStrFolderPath->String.utf8[0]);500 *pwszFilter = '\0'; 501 pStrFolderPath->u16Length = (uint16_t)((uint8_t *)pwszFilter - &pStrFolderPath->String.utf8[0]); 547 502 548 503 /* Convert filter part of the copy to NT speak. */ 549 p szFilter = (char *)&pFilter->String.utf8[(uint8_t *)pszFilter - &pStrFolderPath->String.utf8[0]];504 pwszFilter = (PRTUTF16)&pFilter->String.utf8[(uint8_t *)pwszFilter - &pStrFolderPath->String.utf8[0]]; 550 505 for (;;) 551 506 { 552 char ch = *pszFilter;553 if ( ch== '?')554 *p szFilter = '>';/* The DOS question mark: Matches one char, but dots and end-of-name eats them. */555 else if ( ch== '.')507 RTUTF16 wc = *pwszFilter; 508 if (wc == '?') 509 *pwszFilter = '>'; /* The DOS question mark: Matches one char, but dots and end-of-name eats them. */ 510 else if (wc == '.') 556 511 { 557 char ch2 = pszFilter[1];558 if ( ch2 == '*' || ch2 == '?')559 *p szFilter = '"';/* The DOS dot: Matches a dot or end-of-name. */512 RTUTF16 wc2 = pwszFilter[1]; 513 if (wc2 == '*' || wc2 == '?') 514 *pwszFilter = '"'; /* The DOS dot: Matches a dot or end-of-name. */ 560 515 } 561 else if ( ch== '*')516 else if (wc == '*') 562 517 { 563 if (p szFilter[1] == '.')564 *p szFilter = '<';/* The DOS star: Matches zero or more chars except the DOS dot.*/518 if (pwszFilter[1] == '.') 519 *pwszFilter = '<'; /* The DOS star: Matches zero or more chars except the DOS dot.*/ 565 520 } 566 else if ( ch== '\0')521 else if (wc == '\0') 567 522 break; 568 p szFilter++;523 pwszFilter++; 569 524 } 570 525 } … … 581 536 * but if we do we should accept it only for the root. 582 537 */ 583 else if (p szFilter)538 else if (pwszFilter) 584 539 { 585 540 pFilter = pStrFolderPath; 586 pStrFolderPath = vboxSfOs2StrDup(pFilter->String.ach, pszFilter - pFilter->String.ach); 587 if (!pStrFolderPath) 541 pStrFolderPath = vboxSfOs2StrAlloc(pwszFilter - pFilter->String.utf16); 542 if (pStrFolderPath) 543 { 544 pStrFolderPath->u16Length = (uint16_t)((uintptr_t)pwszFilter - (uintptr_t)pFilter->String.utf16); 545 memcpy(pStrFolderPath->String.utf16, pFilter->String.utf16, pStrFolderPath->u16Length); 546 pStrFolderPath->String.utf16[pStrFolderPath->u16Length / sizeof(RTUTF16)] = '\0'; 547 } 548 else 588 549 rc = ERROR_NOT_ENOUGH_MEMORY; 589 550 } 590 else if (!p szFilter && pStrFolderPath->u16Length > 1)551 else if (!pwszFilter && pStrFolderPath->u16Length > 1) 591 552 { 592 LogFlow(("FS32_FINDFIRST: Trailing slash (% s)\n", pStrFolderPath->String.utf8));553 LogFlow(("FS32_FINDFIRST: Trailing slash (%ls)\n", pStrFolderPath->String.utf16)); 593 554 rc = ERROR_PATH_NOT_FOUND; 594 555 } 595 556 else 596 LogFlow(("FS32_FINDFIRST: Root dir (% s)\n", pStrFolderPath->String.utf8));557 LogFlow(("FS32_FINDFIRST: Root dir (%ls)\n", pStrFolderPath->String.utf16)); 597 558 598 559 /* … … 626 587 | SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ | SHFL_CF_ACCESS_DENYNONE; 627 588 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 628 LogFlow(("FS32_FINDFIRST: VbglR0SfCreate(% s) -> %Rrc Result=%d fMode=%#x hHandle=%#RX64\n",629 pStrFolderPath->String. ach, vrc, pParams->Result, pParams->Info.Attr.fMode, pParams->Handle));589 LogFlow(("FS32_FINDFIRST: VbglR0SfCreate(%ls) -> %Rrc Result=%d fMode=%#x hHandle=%#RX64\n", 590 pStrFolderPath->String.utf16, vrc, pParams->Result, pParams->Info.Attr.fMode, pParams->Handle)); 630 591 if (RT_SUCCESS(vrc)) 631 592 { … … 681 642 else 682 643 { 683 LogFlow(("FS32_FINDFIRST: VbglR0SfCreate returns NIL handle for '% s'\n", pStrFolderPath->String.utf8));644 LogFlow(("FS32_FINDFIRST: VbglR0SfCreate returns NIL handle for '%ls'\n", pStrFolderPath->String.utf16)); 684 645 rc = ERROR_PATH_NOT_FOUND; 685 646 } -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFInternal.h
r75405 r76108 47 47 #include <iprt/list.h> 48 48 #include <VBox/VBoxGuestLibSharedFolders.h> 49 #include <VBox/VBoxGuest.h> 49 50 50 51 … … 182 183 /** Staging area for staging a full FILEFINDBUF4L (+ 32 safe bytes). */ 183 184 uint8_t abStaging[RT_ALIGN_32(sizeof(FILEFINDBUF4L) + 32, 8)]; 184 /** For temporary convertion to UTF-8 so we can use KernStrFromUcs to get185 * string encoded according to the process codepage. */186 RTUTF16 wszTmp[260];187 185 } VBOXSFFSBUF; 188 186 AssertCompileSizeAlignment(VBOXSFFSBUF, 8); … … 224 222 extern VBGLSFCLIENT g_SfClient; 225 223 226 PSHFLSTRING vboxSfOs2StrAlloc(size_t c chLength);227 PSHFLSTRING vboxSfOs2StrDup( const char *pachSrc, size_t cchSrc);224 PSHFLSTRING vboxSfOs2StrAlloc(size_t cwcLength); 225 PSHFLSTRING vboxSfOs2StrDup(PCSHFLSTRING pSrc); 228 226 void vboxSfOs2StrFree(PSHFLSTRING pStr); 229 227 230 228 APIRET vboxSfOs2ResolvePath(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd, 231 229 PVBOXSFFOLDER *ppFolder, PSHFLSTRING *ppStrFolderPath); 230 APIRET vboxSfOs2ResolvePathEx(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd, uint32_t offStrInBuf, 231 PVBOXSFFOLDER *ppFolder, void **ppvBuf); 232 232 void vboxSfOs2ReleasePathAndFolder(PSHFLSTRING pStrPath, PVBOXSFFOLDER pFolder); 233 233 void vboxSfOs2ReleaseFolder(PVBOXSFFOLDER pFolder); … … 244 244 DECLASM(PVBOXSFVP) Fsh32GetVolParams(USHORT hVbp, PVPFSI *ppVpFsi /*optional*/); 245 245 246 247 248 /** Request structure for vboxSfOs2HostReqCreate. */ 249 typedef struct VBOXSFCREATEREQ 250 { 251 VBGLIOCIDCHGCMFASTCALL Hdr; 252 VMMDevHGCMCall Call; 253 VBoxSFParmCreate Parms; 254 SHFLCREATEPARMS CreateParms; 255 SHFLSTRING StrPath; 256 } VBOXSFCREATEREQ; 257 258 /** 259 * SHFL_FN_CREATE request. 260 */ 261 DECLINLINE(int) vboxSfOs2HostReqCreate(PVBOXSFFOLDER pFolder, VBOXSFCREATEREQ *pReq) 262 { 263 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient, 264 SHFL_FN_CREATE, SHFL_CPARMS_CREATE, 265 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size); 266 267 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit; 268 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root; 269 270 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded; 271 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size; 272 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL); 273 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST; 274 275 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_Embedded; 276 pReq->Parms.pCreateParms.u.Embedded.cbData = sizeof(pReq->CreateParms); 277 pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL); 278 pReq->Parms.pCreateParms.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH; 279 280 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, 281 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size); 282 if (RT_SUCCESS(vrc)) 283 vrc = pReq->Call.header.result; 284 return vrc; 285 } 286 287 246 288 #endif 247 289
Note:
See TracChangeset
for help on using the changeset viewer.