Changeset 75337 in vbox for trunk/src/VBox/Additions/os2/VBoxSF
- Timestamp:
- Nov 9, 2018 1:39:01 AM (6 years ago)
- Location:
- trunk/src/VBox/Additions/os2/VBoxSF
- Files:
-
- 3 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/os2/VBoxSF/Makefile.kmk
r69339 r75337 29 29 # 30 30 31 ifneq ($(KBUILD_HOST),os2) 32 VBOX_USE_WATCOM_FOR_OS2 = 1 33 KBUILD_TARGET = os2 34 BUILD_TARGET = os2 35 KBUILD_TARGET_ARCH = x86 36 BUILD_TARGET_ARCH = x86 37 endif 38 31 39 SUB_DEPTH = ../../../../.. 32 40 include $(KBUILD_PATH)/subheader.kmk 33 41 34 VBOXSF_USE_WATCOM=1 35 TEMPLATE_VBoxGuestR0Watcom = xxx 36 TEMPLATE_VBoxGuestR0Watcom_EXTENDS = VBOXGUESTR0 37 TEMPLATE_VBoxGuestR0Watcom_TOOL = OPENWATCOM 38 TEMPLATE_VBoxGuestR0Watcom_CTOOL = OPENWATCOM 39 TEMPLATE_VBoxGuestR0Watcom_CXXTOOL = OPENWATCOM 40 TEMPLATE_VBoxGuestR0Watcom_LDTOOL = OPENWATCOM-WL 41 TEMPLATE_VBoxGuestR0Watcom_CINCS = \ 42 $(PATH_TOOL_OPENWATCOM)/h \ 43 $(PATH_TOOL_OPENWATCOM)/h/os2 \ 44 $(PATH_ROOT)/include \ 45 /libc/svn/trunk/libc/include # for os2ddk 46 TEMPLATE_VBoxGuestR0Watcom_CXXINCS = $(TEMPLATE_VBoxGuestR0Watcom_CINCS) 47 TEMPLATE_VBoxGuestR0Watcom_CFLAGS = -s -ze -w4 -d2 -hc -nt=TEXT32 -nc=CODE -4 48 TEMPLATE_VBoxGuestR0Watcom_CXXFLAGS = $(TEMPLATE_VBoxGuestR0Watcom_CFLAGS) 49 50 TEMPLATE_VBoxGuestR0Watcom_LDFLAGS = \ 51 form os2 lx physdevice \ 52 option NODefaultlibs \ 53 debug codeview all \ 54 option symfile 55 TEMPLATE_VBoxGuestR0Watcom_LIBS = $(NO_SUCH_VARIABLE) 56 57 58 #?DLLS += VBoxSF 42 # 43 # Debug segment name hack for NASM and dependency workaround (see valkit/bootsector). 44 # 45 include $(KBUILD_PATH)/tools/NASM.kmk 46 TOOL_VBoxNasmDot = Our version of the NASM tool 47 ifndef TOOL_VBoxNasmDot_PATH 48 ifdef TOOL_VBoxNasm_PATH 49 TOOL_VBoxNasmDot_PATH = $(TOOL_VBoxNasm_PATH) 50 else 51 TOOL_VBoxNasmDot_PATH := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/nasm/v*.*))) 52 if "$(TOOL_VBoxNasmDot_PATH)" == "" && "$(KBUILD_DEVTOOLS_HST_ALT)" != "" 53 TOOL_VBoxNasmDot_PATH := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST_ALT)/nasm/v*.*))) 54 endif 55 endif 56 endif 57 ifneq ($(TOOL_VBoxNasmDot_PATH),) 58 TOOL_VBoxNasmDot_AS ?= $(TOOL_VBoxNasmDot_PATH)/nasm$(HOSTSUFF_EXE) 59 else 60 TOOL_VBoxNasmDot_AS ?= nasm$(HOSTSUFF_EXE) 61 endif 62 TOOL_VBoxNasmDot_ASFLAGS ?= $(TOOL_NASM_ASFLAGS) 63 TOOL_VBoxNasmDot_COMPILE_AS_OUTPUT = $(outbase).lst 64 TOOL_VBoxNasmDot_COMPILE_AS_DEPEND = $(dotseg_1_TARGET) 65 TOOL_VBoxNasmDot_COMPILE_AS_DEPORD = 66 define TOOL_VBoxNasmDot_COMPILE_AS_CMDS 67 ifdef TOOL_VBoxNasmDot_USE_KSUBMIT 68 $(QUIET)kmk_builtin_kSubmit -C $(PATH_OUT_BASE) -- $(TOOL_VBoxNasmDot_AS)\ 69 $(flags) $(addsuffix /,$(addprefix -i, $(incs))) $(addprefix -D, $(defs))\ 70 -l $(outbase).lst\ 71 -o $(obj)\ 72 -MD "$(dep)" -MP\ 73 $(abspath $(source)) 74 else 75 $(QUIET)$(REDIRECT) -C $(PATH_OUT_BASE) -- $(TOOL_VBoxNasmDot_AS)\ 76 $(flags) $(addsuffix /,$(addprefix -i, $(incs))) $(addprefix -D, $(defs))\ 77 -l $(outbase).lst\ 78 -o $(obj)\ 79 -MD "$(dep)" -MP\ 80 $(abspath $(source)) 81 endif 82 $(QUIET)"$(dotseg_1_TARGET)" "$(obj)" 83 endef 84 85 # 86 # Tool for renaming segments and groups from '$debug_*' to '.debug_*'. 87 # 88 BLDPROGS += dotseg 89 dotseg_TEMPLATE = VBoxBldProg 90 dotseg_SOURCES = dotseg.cpp 91 92 93 # 94 # IFS kBuild template tweak. 95 # 96 TEMPLATE_VBoxR0DrvIFS = Hack to make sure we link a library. IFS must not be physical devices, but DLLs! 97 TEMPLATE_VBoxR0DrvIFS_EXTENDS = VBOXGUESTR0 98 ifdef VBOX_USE_WATCOM_FOR_OS2 99 TEMPLATE_VBoxR0DrvIFS_LDFLAGS = $(subst physdevice,dll, $(TEMPLATE_VBOXGUESTR0_LDFLAGS)) 100 endif 101 TEMPLATE_VBoxR0DrvIFS_SYSSUFF = .ifs 102 TEMPLATE_VBoxR0DrvIFS_DLLSUFF = .ifs 103 TEMPLATE_VBoxR0DrvIFS_ASTOOL = VBoxNasmDot 104 105 106 # 107 # The OS/2 shared folder installable file system driver (IFS). 108 # 59 109 SYSMODS += VBoxSF 60 ifdef VBOXSF_USE_WATCOM 61 VBoxSF_TEMPLATE = VBoxGuestR0Watcom 62 else 63 VBoxSF_TEMPLATE = VBOXGUESTR0 64 endif 65 VBoxSF_SYSSUFF = .ifs 66 VBoxSF_DLLSUFF = .ifs 110 VBoxSF_TEMPLATE = VBoxR0DrvIFS 67 111 VBoxSF_DEFS = VBOX_WITH_HGCM 68 112 VBoxSF_INCS := \ 69 113 . \ 70 114 $(PATH_ROOT)/src/VBox/Runtime/include 71 ifdef VBOX SF_USE_WATCOM115 ifdef VBOX_USE_WATCOM_FOR_OS2 72 116 VBoxSF_LDFLAGS := \ 73 117 OPTION MODNAME='VBoxSF' \ … … 126 170 EXPORT 'FS_SETSWAP' \ 127 171 EXPORT 'FS_SHUTDOWN' \ 172 EXPORT 'FS_VERIFYUNCNAME' \ 128 173 EXPORT 'FS_WRITE' 129 174 # 32-bit entry points. 130 175 VBoxSF_LDFLAGS += \ 131 EXPORT 'FS32_CHGFILEPTR' \132 176 EXPORT 'FS32_CHGFILEPTRL' \ 133 177 EXPORT 'FS32_READ' \ … … 148 192 VBoxSFFind.cpp \ 149 193 VBoxSFInit.cpp 150 ifndef VBOX SF_USE_WATCOM194 ifndef VBOX_USE_WATCOM_FOR_OS2 151 195 VBoxSF_SOURCES += \ 152 196 VBoxSF.def … … 155 199 $(VBOX_LIB_VBGL_R0) \ 156 200 $(VBOX_LIB_IPRT_GUEST_R0) 157 ifdef VBOX SF_USE_WATCOM201 ifdef VBOX_USE_WATCOM_FOR_OS2 158 202 VBoxSF_LIBS += $(PATH_IGCC)/lib/libend.lib 159 203 else … … 161 205 endif 162 206 207 208 # 209 # Simple utility for attaching a shared folder to a drive letter. 210 # 211 PROGRAMS += VBoxSFUtil 212 VBoxSFUtil_TEMPLATE = DUMMY 213 VBoxSFUtil_TOOL = OPENWATCOM 214 VBoxSFUtil_ASTOOL = NASM 215 VBoxSFUtil_ASFLAGS = -f obj -DASM_FORMAT_OMF 216 VBoxSFUtil_INCS = $(PATH_TOOL_OPENWATCOM)/h/os2 217 VBoxSFUtil_LDFLAGS = -bcl=os2v2 218 VBoxSFUtil_SOURCES = \ 219 VBoxSFUtil.cpp \ 220 VBoxSFUtilA.asm 221 222 #PROGRAMS += VBoxSFUtil16 223 #VBoxSFUtil16_TEMPLATE = DUMMY 224 #VBoxSFUtil16_TOOL = OPENWATCOM-16 225 #VBoxSFUtil16_ASTOOL = NASM 226 #VBoxSFUtil16_INCS = $(PATH_TOOL_OPENWATCOM)/h/os2 227 #VBoxSFUtil16_LDFLAGS = -bcl=os2 228 #VBoxSFUtil16_SOURCES = VBoxSFUtil.cpp 229 230 163 231 include $(FILE_KBUILD_SUB_FOOTER) 164 232 -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSF.cpp
r68612 r75337 38 38 #include <VBox/log.h> 39 39 #include <iprt/assert.h> 40 40 #include <iprt/ctype.h> 41 #include <iprt/mem.h> 42 43 #include <iprt/asm.h> 44 #include <iprt/asm-amd64-x86.h> 45 46 47 /********************************************************************************************************************************* 48 * Defined Constants And Macros * 49 *********************************************************************************************************************************/ 50 /** Max folder name length, including terminator. 51 * Easier to deal with stack buffers if we put a reasonable limit on the. */ 52 #define VBOXSFOS2_MAX_FOLDER_NAME 64 53 54 55 /********************************************************************************************************************************* 56 * Global Variables * 57 *********************************************************************************************************************************/ 58 /** The shared mutex protecting folders list, drives and the connection. */ 59 MutexLock_t g_MtxFolders; 60 /** The shared folder service client structure. */ 61 VBGLSFCLIENT g_SfClient; 62 /** Set if g_SfClient is valid, clear if not. */ 63 bool g_fIsConnectedToService = false; 64 /** List of active folder (PVBOXSFFOLDER). */ 65 RTLISTANCHOR g_FolderHead; 66 /** This is incremented everytime g_FolderHead is modified. */ 67 uint32_t volatile g_uFolderRevision; 68 /** Folders mapped on drive letters. Pointers include a reference. */ 69 PVBOXSFFOLDER g_apDriveFolders[26]; 70 71 72 73 /** 74 * Generic IPRT -> OS/2 status code converter. 75 * 76 * @returns OS/2 status code. 77 * @param vrc IPRT/VBox status code. 78 * @param rcDefault The OS/2 status code to return when there 79 * is no translation. 80 */ 81 APIRET vboxSfOs2ConvertStatusToOs2(int vrc, APIRET rcDefault) 82 { 83 switch (vrc) 84 { 85 default: return rcDefault; 86 87 case VERR_FILE_NOT_FOUND: return ERROR_FILE_NOT_FOUND; 88 case VERR_PATH_NOT_FOUND: return ERROR_PATH_NOT_FOUND; 89 case VERR_SHARING_VIOLATION: return ERROR_SHARING_VIOLATION; 90 case VERR_ACCESS_DENIED: return ERROR_ACCESS_DENIED; 91 case VERR_ALREADY_EXISTS: return ERROR_ACCESS_DENIED; 92 case VERR_WRITE_PROTECT: return ERROR_WRITE_PROTECT; 93 case VERR_IS_A_DIRECTORY: return ERROR_DIRECTORY; 94 case VINF_SUCCESS: return NO_ERROR; 95 } 96 } 97 98 99 /** 100 * Gets the delta for the local timezone, in minutes. 101 * 102 * We need to do this once for each API call rather than over and over again for 103 * each date/time conversion, so as not to create an update race. 104 * 105 * @returns Delta in minutes. Current thinking is that positive means timezone 106 * is west of UTC, while negative is east of it. 107 */ 108 int16_t vboxSfOs2GetLocalTimeDelta(void) 109 { 110 GINFOSEG volatile *pGis = (GINFOSEG volatile *)&KernSISData; 111 if (pGis) 112 { 113 uint16_t cDelta = pGis->timezone; 114 if (cDelta != 0 && cDelta != 0xffff) 115 return (int16_t)cDelta; 116 } 117 return 0; 118 } 119 120 121 /** 122 * Helper for converting from IPRT timespec format to OS/2 DATE/TIME. 123 * 124 * @param pDosDate The output DOS date. 125 * @param pDosTime The output DOS time. 126 * @param SrcTimeSpec The IPRT input timestamp. 127 * @param cMinLocalTimeDelta The timezone delta in minutes. 128 */ 129 void vboxSfOs2DateTimeFromTimeSpec(FDATE *pDosDate, FTIME *pDosTime, RTTIMESPEC SrcTimeSpec, int16_t cMinLocalTimeDelta) 130 { 131 if (cMinLocalTimeDelta != 0) 132 RTTimeSpecAddSeconds(&SrcTimeSpec, cMinLocalTimeDelta * 60); 133 134 RTTIME Time; 135 if ( RTTimeSpecGetNano(&SrcTimeSpec) >= RTTIME_OFFSET_DOS_TIME 136 && RTTimeExplode(&Time, &SrcTimeSpec)) 137 { 138 pDosDate->year = Time.i32Year - 1980; 139 pDosDate->month = Time.u8Month; 140 pDosDate->day = Time.u8MonthDay; 141 pDosTime->hours = Time.u8Hour; 142 pDosTime->minutes = Time.u8Minute; 143 pDosTime->twosecs = Time.u8Second / 2; 144 } 145 else 146 { 147 pDosDate->year = 0; 148 pDosDate->month = 1; 149 pDosDate->day = 1; 150 pDosTime->hours = 0; 151 pDosTime->minutes = 0; 152 pDosTime->twosecs = 0; 153 } 154 } 155 156 157 /** 158 * Helper for converting from OS/2 DATE/TIME to IPRT timespec format. 159 * 160 * @returns pDstTimeSpec on success, NULL if invalid input. 161 * @param DosDate The input DOS date. 162 * @param DosTime The input DOS time. 163 * @param cMinLocalTimeDelta The timezone delta in minutes. 164 * @param pDstTimeSpec The IPRT output timestamp. 165 */ 166 PRTTIMESPEC vboxSfOs2DateTimeToTimeSpec(FDATE DosDate, FTIME DosTime, int16_t cMinLocalTimeDelta, PRTTIMESPEC pDstTimeSpec) 167 { 168 RTTIME Time; 169 Time.i32Year = DosDate.year + 1980; 170 Time.u8Month = DosDate.month; 171 Time.u8WeekDay = UINT8_MAX; 172 Time.u16YearDay = 0; 173 Time.u8MonthDay = DosDate.day; 174 Time.u8Hour = DosTime.hours; 175 Time.u8Minute = DosTime.minutes; 176 Time.u8Second = DosTime.twosecs * 2; 177 Time.u32Nanosecond = 0; 178 Time.fFlags = RTTIME_FLAGS_TYPE_LOCAL; 179 Time.offUTC = cMinLocalTimeDelta; 180 if (RTTimeLocalNormalize(&Time)) 181 return RTTimeImplode(pDstTimeSpec, &Time); 182 return NULL; 183 } 184 185 186 /********************************************************************************************************************************* 187 * Shared Folder String Buffer Management * 188 *********************************************************************************************************************************/ 189 190 /** 191 * Allocates a SHFLSTRING buffer. 192 * 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); 201 if (pStr) 202 { 203 pStr->u16Size = (uint16_t)(cchLength + 1); 204 pStr->u16Length = 0; 205 pStr->String.ach[0] = '\0'; 206 return pStr; 207 } 208 return NULL; 209 } 210 211 212 /** 213 * Duplicates a UTF-8 string into a SHFLSTRING buffer. 214 * 215 * @returns Pointer to a SHFLSTRING buffer containing the copy. 216 * 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 } 235 } 236 return NULL; 237 } 238 239 240 /** 241 * Frees a SHLFSTRING buffer. 242 * 243 * @param pStr The buffer to free. 244 */ 245 void vboxSfOs2StrFree(PSHFLSTRING pStr) 246 { 247 if (pStr) 248 VbglR0PhysHeapFree(pStr); 249 } 250 251 252 253 /********************************************************************************************************************************* 254 * Folders, Paths and Service Connection. * 255 *********************************************************************************************************************************/ 256 257 /** 258 * Ensures that we're connected to the host service. 259 * 260 * @returns VBox status code. 261 * @remarks Caller owns g_MtxFolder exclusively! 262 */ 263 static int vboxSfOs2EnsureConnected(void) 264 { 265 if (g_fIsConnectedToService) 266 return VINF_SUCCESS; 267 268 int rc = VbglR0SfConnect(&g_SfClient); 269 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 } 280 else 281 LogRel(("VbglR0SfConnect failed: %Rrc\n", rc)); 282 return rc; 283 } 284 285 286 /** 287 * Destroys a folder when the reference count has reached zero. 288 * 289 * @param pFolder The folder to destroy. 290 */ 291 static void vboxSfOs2DestroyFolder(PVBOXSFFOLDER pFolder) 292 { 293 /* Note! We won't get there while the folder is on the list. */ 294 LogRel(("vboxSfOs2ReleaseFolder: Destroying %p [%s]\n", pFolder, pFolder->szName)); 295 VbglR0SfUnmapFolder(&g_SfClient, &pFolder->hHostFolder); 296 RT_ZERO(pFolder); 297 RTMemFree(pFolder); 298 } 299 300 301 /** 302 * Releases a reference to a folder. 303 * 304 * @param pFolder The folder to release. 305 */ 306 void vboxSfOs2ReleaseFolder(PVBOXSFFOLDER pFolder) 307 { 308 if (pFolder) 309 { 310 uint32_t cRefs = ASMAtomicDecU32(&pFolder->cRefs); 311 AssertMsg(cRefs < _64K, ("%#x\n", cRefs)); 312 if (!cRefs) 313 vboxSfOs2DestroyFolder(pFolder); 314 } 315 } 316 317 318 /** 319 * Retain a reference to a folder. 320 * 321 * @param pFolder The folder to release. 322 */ 323 void vboxSfOs2RetainFolder(PVBOXSFFOLDER pFolder) 324 { 325 uint32_t cRefs = ASMAtomicIncU32(&pFolder->cRefs); 326 AssertMsg(cRefs < _64K, ("%#x\n", cRefs)); 327 } 328 329 330 /** 331 * Locates and retains a folder structure. 332 * 333 * @returns Folder matching the name, NULL of not found. 334 * @remarks Caller owns g_MtxFolder. 335 */ 336 static PVBOXSFFOLDER vboxSfOs2FindAndRetainFolder(const char *pachName, size_t cchName) 337 { 338 PVBOXSFFOLDER pCur; 339 RTListForEach(&g_FolderHead, pCur, VBOXSFFOLDER, ListEntry) 340 { 341 if ( pCur->cchName == cchName 342 && RTStrNICmpAscii(pCur->szName, pachName, cchName) == 0) 343 { 344 uint32_t cRefs = ASMAtomicIncU32(&pCur->cRefs); 345 AssertMsg(cRefs < _64K, ("%#x\n", cRefs)); 346 return pCur; 347 } 348 } 349 return NULL; 350 } 351 352 353 /** 354 * Maps a folder, linking it into the list of folders. 355 * 356 * One reference is retained for the caller, which must pass it on or release 357 * it. The list also have a reference to it. 358 * 359 * @returns VBox status code. 360 * @param pName The name of the folder to map. 361 * @param ppFolder Where to return the folder structure on success. 362 * 363 * @remarks Caller owns g_MtxFolder exclusively! 364 */ 365 static int vboxSfOs2MapFolder(PSHFLSTRING pName, PVBOXSFFOLDER *ppFolder) 366 { 367 int rc; 368 PVBOXSFFOLDER pNew = (PVBOXSFFOLDER)RTMemAlloc(RT_UOFFSETOF_DYN(VBOXSFFOLDER, szName[pName->u16Length + 1])); 369 if (pNew != NULL) 370 { 371 pNew->u32Magic = VBOXSFFOLDER_MAGIC; 372 pNew->cRefs = 2; /* (List reference + the returned reference.) */ 373 pNew->cOpenFiles = 0; 374 pNew->cDrives = 0; 375 RT_ZERO(pNew->hHostFolder); 376 pNew->hVpb = 0; 377 pNew->cchName = (uint8_t)pName->u16Length; 378 memcpy(pNew->szName, pName->String.utf8, pName->u16Length); 379 pNew->szName[pName->u16Length] = '\0'; 380 381 rc = VbglR0SfMapFolder(&g_SfClient, pName, &pNew->hHostFolder); 382 if (RT_SUCCESS(rc)) 383 { 384 RTListAppend(&g_FolderHead, &pNew->ListEntry); 385 ASMAtomicIncU32(&g_uFolderRevision); 386 LogRel(("vboxSfOs2MapFolder: %p - %s\n", pNew, pNew->szName)); 387 388 *ppFolder = pNew; 389 } 390 else 391 { 392 LogRel(("vboxSfOs2MapFolder: VbglR0SfMapFolder(,%.*s,) -> %Rrc\n", pName->u16Length, pName->String.utf8, rc)); 393 RTMemFree(pNew); 394 } 395 } 396 else 397 { 398 LogRel(("vboxSfOs2MapFolder: Out of memory :-(\n")); 399 rc = VERR_NO_MEMORY; 400 } 401 return rc; 402 } 403 404 405 /** 406 * Worker for vboxSfOs2UncPrefixLength. 407 */ 408 DECLINLINE(size_t) vboxSfOs2CountLeadingSlashes(const char *pszPath) 409 { 410 size_t cchSlashes = 0; 411 char ch; 412 while ((ch = *pszPath) == '\\' || ch == '/') 413 cchSlashes++, pszPath++; 414 return cchSlashes; 415 } 416 417 418 /** 419 * Checks for a VBox UNC prefix (server + slashes) and determins its length when 420 * found. 421 * 422 * @returns Length of VBoxSF UNC prefix, 0 if not VBoxSF UNC prefix. 423 * @param pszPath The possible UNC path. 424 */ 425 DECLINLINE(size_t) vboxSfOs2UncPrefixLength(const char *pszPath) 426 { 427 char ch; 428 if ( ((ch = pszPath[0]) == '\\' || ch == '/') 429 && ((ch = pszPath[1]) == '\\' || ch == '/') 430 && ((ch = pszPath[2]) == 'V' || ch == 'v') 431 && ((ch = pszPath[3]) == 'B' || ch == 'b') 432 && ((ch = pszPath[4]) == 'O' || ch == 'o') 433 && ((ch = pszPath[5]) == 'X' || ch == 'x') 434 && ((ch = pszPath[6]) == 'S' || ch == 's') 435 ) 436 { 437 /* \\VBoxSf\ */ 438 if ( ((ch = pszPath[7]) == 'F' || ch == 'f') 439 && ((ch = pszPath[8]) == '\\' || ch == '/') ) 440 return vboxSfOs2CountLeadingSlashes(&pszPath[9]) + 9; 441 442 /* \\VBoxSvr\ */ 443 if ( ((ch = pszPath[7]) == 'V' || ch == 'v') 444 && ((ch = pszPath[8]) == 'R' || ch == 'r') 445 && ((ch = pszPath[9]) == '\\' || ch == '/') ) 446 return vboxSfOs2CountLeadingSlashes(&pszPath[10]) + 10; 447 448 /* \\VBoxSrv\ */ 449 if ( ((ch = pszPath[7]) == 'R' || ch == 'r') 450 && ((ch = pszPath[8]) == 'V' || ch == 'v') 451 && ((ch = pszPath[9]) == '\\' || ch == '/') ) 452 return vboxSfOs2CountLeadingSlashes(&pszPath[10]) + 10; 453 } 454 455 return 0; 456 } 457 458 459 /** 460 * Converts a path to UTF-8 and puts it in a VBGL friendly buffer. 461 * 462 * @returns OS/2 status code 463 * @param pszFolderPath The path to convert. 464 * @param ppStr Where to return the pointer to the buffer. Free 465 * using vboxSfOs2FreePath. 466 */ 467 APIRET vboxSfOs2ConvertPath(const char *pszFolderPath, PSHFLSTRING *ppStr) 468 { 469 /* Skip unnecessary leading slashes. */ 470 char ch = *pszFolderPath; 471 if (ch == '\\' || ch == '/') 472 while ((ch = pszFolderPath[1]) == '\\' || ch == '/') 473 pszFolderPath++; 474 475 /** @todo do proper codepage -> utf8 conversion and straighten out 476 * everything... */ 477 size_t cchSrc = strlen(pszFolderPath); 478 PSHFLSTRING pDst = vboxSfOs2StrAlloc(cchSrc); 479 if (pDst) 480 { 481 pDst->u16Length = (uint16_t)cchSrc; 482 memcpy(pDst->String.utf8, pszFolderPath, cchSrc); 483 pDst->String.utf8[cchSrc] = '\0'; 484 *ppStr = pDst; 485 return NO_ERROR; 486 } 487 *ppStr = NULL; 488 return ERROR_NOT_ENOUGH_MEMORY; 489 } 490 491 492 /** 493 * Counterpart to vboxSfOs2ResolvePath. 494 * 495 * @param pStrPath The path to free. 496 * @param pFolder The folder to release. 497 */ 498 void vboxSfOs2ReleasePathAndFolder(PSHFLSTRING pStrPath, PVBOXSFFOLDER pFolder) 499 { 500 if (pStrPath) 501 VbglR0PhysHeapFree(pStrPath); 502 if (pFolder) 503 { 504 uint32_t cRefs = ASMAtomicDecU32(&pFolder->cRefs); 505 Assert(cRefs < _64K); 506 if (!cRefs) 507 vboxSfOs2DestroyFolder(pFolder); 508 } 509 } 510 511 512 /** 513 * Worker for vboxSfOs2ResolvePath() for dynamically mapping folders for UNC 514 * paths. 515 * 516 * @returns OS/2 status code. 517 * @param pachFolderName The folder to map. Not necessarily zero terminated 518 * at the end of the folder name! 519 * @param cchFolderName The length of the folder name. 520 * @param uRevBefore The previous folder list revision. 521 * @param ppFolder Where to return the pointer to the retained folder. 522 */ 523 DECL_NO_INLINE(static, int) vboxSfOs2AttachUncAndRetain(const char *pachFolderName, size_t cchFolderName, 524 uint32_t uRevBefore, PVBOXSFFOLDER *ppFolder) 525 { 526 KernRequestExclusiveMutex(&g_MtxFolders); 527 528 /* 529 * Check if someone raced us to it. 530 */ 531 if (uRevBefore != g_uFolderRevision) 532 { 533 PVBOXSFFOLDER pFolder = vboxSfOs2FindAndRetainFolder(pachFolderName, cchFolderName); 534 if (pFolder) 535 { 536 KernReleaseExclusiveMutex(&g_MtxFolders); 537 *ppFolder = pFolder; 538 return NO_ERROR; 539 } 540 } 541 542 int rc = vboxSfOs2EnsureConnected(); 543 if (RT_SUCCESS(rc)) 544 { 545 /* 546 * Copy the name into the buffer format that Vbgl desires. 547 */ 548 PSHFLSTRING pStrName = vboxSfOs2StrDup(pachFolderName, cchFolderName); 549 if (pStrName) 550 { 551 /* 552 * Do the attaching. 553 */ 554 rc = vboxSfOs2MapFolder(pStrName, ppFolder); 555 vboxSfOs2StrFree(pStrName); 556 if (RT_SUCCESS(rc)) 557 { 558 KernReleaseExclusiveMutex(&g_MtxFolders); 559 LogRel(("vboxSfOs2AttachUncAndRetain: Successfully attached '%s' (as UNC).\n", (*ppFolder)->szName)); 560 return NO_ERROR; 561 } 562 563 if (rc == VERR_NO_MEMORY) 564 rc = ERROR_NOT_ENOUGH_MEMORY; 565 else 566 rc = ERROR_PATH_NOT_FOUND; 567 } 568 else 569 rc = ERROR_NOT_ENOUGH_MEMORY; 570 } 571 else 572 rc = ERROR_PATH_NOT_FOUND; 573 574 KernReleaseExclusiveMutex(&g_MtxFolders); 575 return rc; 576 } 577 578 579 /** 580 * Resolves the given path to a folder structure and folder relative string. 581 * 582 * @returns OS/2 status code. 583 * @param pszPath The path to resolve. 584 * @param pCdFsd The IFS dependent CWD structure if present. 585 * @param offCurDirEnd The offset into @a pszPath of the CWD. -1 if not 586 * CWD relative path. 587 * @param ppFolder Where to return the referenced pointer to the folder 588 * structure. Call vboxSfOs2ReleaseFolder() when done. 589 * @param ppStrFolderPath Where to return a buffer holding the folder relative 590 * path component. Free using vboxSfOs2FreePath(). 591 */ 592 APIRET vboxSfOs2ResolvePath(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd, 593 PVBOXSFFOLDER *ppFolder, PSHFLSTRING *ppStrFolderPath) 594 { 595 APIRET rc; 596 597 /* 598 * UNC path? Reject the prefix to be on the safe side. 599 */ 600 char ch = pszPath[0]; 601 if (ch == '\\' || ch == '/') 602 { 603 size_t cchPrefix = vboxSfOs2UncPrefixLength(pszPath); 604 if (cchPrefix > 0) 605 { 606 /* Find the length of the folder name (share). */ 607 const char *pszFolderName = &pszPath[cchPrefix]; 608 size_t cchFolderName = 0; 609 while ((ch = pszFolderName[cchFolderName]) != '\0' && ch != '\\' && ch != '/') 610 { 611 if ((uint8_t)ch >= 0x20 && (uint8_t)ch <= 0x7f && ch != ':') 612 cchFolderName++; 613 else 614 { 615 LogRel(("vboxSfOs2ResolvePath: Invalid share name (@%u): %.*Rhxs\n", 616 cchPrefix + cchFolderName, strlen(pszPath), pszPath)); 617 return ERROR_INVALID_NAME; 618 } 619 } 620 if (cchFolderName >= VBOXSFOS2_MAX_FOLDER_NAME) 621 { 622 LogRel(("vboxSfOs2ResolvePath: Folder name is too long: %u, max %u (%s)\n", 623 cchFolderName, VBOXSFOS2_MAX_FOLDER_NAME, pszPath)); 624 return ERROR_FILENAME_EXCED_RANGE; 625 } 626 627 /* 628 * Look for the share. 629 */ 630 KernRequestSharedMutex(&g_MtxFolders); 631 PVBOXSFFOLDER pFolder = *ppFolder = vboxSfOs2FindAndRetainFolder(pszFolderName, cchFolderName); 632 if (pFolder) 633 { 634 vboxSfOs2RetainFolder(pFolder); 635 KernReleaseSharedMutex(&g_MtxFolders); 636 } 637 else 638 { 639 uint32_t const uRevBefore = g_uFolderRevision; 640 KernReleaseSharedMutex(&g_MtxFolders); 641 rc = vboxSfOs2AttachUncAndRetain(pszFolderName, cchFolderName, uRevBefore, ppFolder); 642 if (rc == NO_ERROR) 643 pFolder = *ppFolder; 644 else 645 return rc; 646 } 647 648 /* 649 * Convert the path and put it in a Vbgl compatible buffer.. 650 */ 651 rc = vboxSfOs2ConvertPath(&pszFolderName[cchFolderName], ppStrFolderPath); 652 if (rc == NO_ERROR) 653 return rc; 654 655 vboxSfOs2ReleaseFolder(pFolder); 656 *ppFolder = NULL; 657 return rc; 658 } 659 660 LogRel(("vboxSfOs2ResolvePath: Unexpected path: %s\n", pszPath)); 661 return ERROR_PATH_NOT_FOUND; 662 } 663 664 /* 665 * Drive letter? 666 */ 667 ch &= ~0x20; /* upper case */ 668 if ( ch >= 'A' 669 && ch <= 'Z' 670 && pszPath[1] == ':') 671 { 672 unsigned iDrive = ch - 'A'; 673 ch = pszPath[2]; 674 if (ch == '\\' || ch == '/') 675 { 676 KernRequestSharedMutex(&g_MtxFolders); 677 PVBOXSFFOLDER pFolder = *ppFolder = g_apDriveFolders[iDrive]; 678 if (pFolder) 679 { 680 vboxSfOs2RetainFolder(pFolder); 681 KernReleaseSharedMutex(&g_MtxFolders); 682 683 /* 684 * Convert the path and put it in a Vbgl compatible buffer.. 685 */ 686 rc = vboxSfOs2ConvertPath(&pszPath[3], ppStrFolderPath); 687 if (rc == NO_ERROR) 688 return rc; 689 690 vboxSfOs2ReleaseFolder(pFolder); 691 *ppFolder = NULL; 692 return rc; 693 } 694 KernReleaseSharedMutex(&g_MtxFolders); 695 LogRel(("vboxSfOs2ResolvePath: No folder mapped on '%s'. Detach race?\n", pszPath)); 696 return ERROR_PATH_NOT_FOUND; 697 } 698 LogRel(("vboxSfOs2ResolvePath: No root slash: '%s'\n", pszPath)); 699 return ERROR_PATH_NOT_FOUND; 700 } 701 LogRel(("vboxSfOs2ResolvePath: Unexpected path: %s\n", pszPath)); 702 RT_NOREF_PV(pCdFsd); RT_NOREF_PV(offCurDirEnd); 703 return ERROR_PATH_NOT_FOUND; 704 } 41 705 42 706 … … 44 708 FS32_EXIT(ULONG uid, ULONG pid, ULONG pdb) 45 709 { 710 LogFlow(("FS32_EXIT: uid=%u pid=%u pdb=%#x\n", uid, pid, pdb)); 46 711 NOREF(uid); NOREF(pid); NOREF(pdb); 47 712 } 48 713 49 714 50 DECLASM(int) 51 FS32_SHUTDOWN(ULONG type, ULONG reserved) 52 { 53 NOREF(type); NOREF(reserved); 715 DECLASM(APIRET) 716 FS32_SHUTDOWN(ULONG uType, ULONG uReserved) 717 { 718 LogFlow(("FS32_SHUTDOWN: type=%u uReserved=%u\n", uType, uReserved)); 719 NOREF(uType); NOREF(uReserved); 54 720 return NO_ERROR; 55 721 } 56 722 57 723 58 DECLASM(int) 59 FS32_ATTACH(ULONG fFlags, PCSZ pszDev, PVBOXSFVP pvpfsd, PVBOXSFCD pcdfsd, PBYTE pszParm, PUSHORT pcbParm) 60 { 61 NOREF(fFlags); NOREF(pszDev); NOREF(pvpfsd); NOREF(pcdfsd); NOREF(pszParm); NOREF(pcbParm); 724 /** 725 * FS32_ATTACH worker: FS_ATTACH 726 */ 727 static APIRET vboxSfOs2Attach(PCSZ pszDev, PVBOXSFVP pVpFsd, PVBOXSFCD pCdFsd, PBYTE pszParam, PUSHORT pcbParam, 728 PSHFLSTRING *ppCleanup) 729 { 730 /* 731 * Check out the parameters, copying the pszParam into a suitable string buffer. 732 */ 733 if (pszDev == NULL || !*pszDev || !RT_C_IS_ALPHA(pszDev[0]) || pszDev[1] != ':' || pszDev[2] != '\0') 734 { 735 LogRel(("vboxSfOs2Attach: Invalid pszDev value:%p:{%s}\n", pszDev, pszDev)); 736 return ERROR_INVALID_PARAMETER; 737 } 738 unsigned const iDrive = (pszDev[0] & ~0x20) - 'A'; 739 740 if (pszParam == NULL || pcbParam == NULL) 741 { 742 LogRel(("vboxSfOs2Attach: NULL parameter buffer or buffer length\n")); 743 return ERROR_INVALID_PARAMETER; 744 } 745 746 PSHFLSTRING pStrName = *ppCleanup = vboxSfOs2StrAlloc(VBOXSFOS2_MAX_FOLDER_NAME - 1); 747 pStrName->u16Length = *pcbParam; 748 if (pStrName->u16Length < 1 || pStrName->u16Length > VBOXSFOS2_MAX_FOLDER_NAME) 749 { 750 LogRel(("vboxSfOs2Attach: Parameter buffer length is out of bounds: %u (min: 1, max " RT_XSTR(VBOXSFOS2_MAX_FOLDER_NAME) ")\n", 751 pStrName->u16Length)); 752 return ERROR_INVALID_PARAMETER; 753 } 754 755 int rc = KernCopyIn(pStrName->String.utf8, pszParam, pStrName->u16Length); 756 if (rc != NO_ERROR) 757 return rc; 758 759 pStrName->u16Length -= 1; 760 if (pStrName->String.utf8[pStrName->u16Length] != '\0') 761 { 762 LogRel(("vboxSfOs2Attach: Parameter not null terminated\n")); 763 return ERROR_INVALID_PARAMETER; 764 } 765 766 /* Make sure it's only ascii and contains not weird stuff. */ 767 unsigned off = pStrName->u16Length; 768 while (off-- > 0) 769 { 770 char const ch = pStrName->String.utf8[off]; 771 if (ch < 0x20 || ch >= 0x7f || ch == ':' || ch == '\\' || ch == '/') 772 { 773 LogRel(("vboxSfOs2Attach: Malformed folder name: %.*Rhxs (off %#x)\n", pStrName->u16Length, pStrName->String.utf8, off)); 774 return ERROR_INVALID_PARAMETER; 775 } 776 } 777 778 if (!pVpFsd) 779 { 780 LogRel(("vboxSfOs2Attach: pVpFsd is NULL\n")); 781 return ERROR_INVALID_PARAMETER; 782 } 783 784 /* 785 * Look for the folder to see if we're already using it. Map it if needed. 786 */ 787 KernRequestExclusiveMutex(&g_MtxFolders); 788 if (g_apDriveFolders[iDrive] == NULL) 789 { 790 791 PVBOXSFFOLDER pFolder = vboxSfOs2FindAndRetainFolder(pStrName->String.ach, pStrName->u16Length); 792 if (!pFolder) 793 { 794 rc = vboxSfOs2EnsureConnected(); 795 if (RT_SUCCESS(rc)) 796 rc = vboxSfOs2MapFolder(pStrName, &pFolder); 797 } 798 if (pFolder && RT_SUCCESS(rc)) 799 { 800 pFolder->cDrives += 1; 801 g_apDriveFolders[iDrive] = pFolder; 802 803 pVpFsd->u32Magic = VBOXSFVP_MAGIC; 804 pVpFsd->pFolder = pFolder; 805 806 KernReleaseExclusiveMutex(&g_MtxFolders); 807 808 LogRel(("vboxSfOs2Attach: Successfully attached '%s' to '%s'.\n", pFolder->szName, pszDev)); 809 return NO_ERROR; 810 } 811 812 KernReleaseExclusiveMutex(&g_MtxFolders); 813 return ERROR_FILE_NOT_FOUND; 814 } 815 KernReleaseExclusiveMutex(&g_MtxFolders); 816 817 LogRel(("vboxSfOs2Attach: Already got a folder on '%s'!\n", pszDev)); 818 RT_NOREF(pCdFsd); 819 return ERROR_BUSY_DRIVE; 820 } 821 822 823 /** 824 * FS32_ATTACH worker: FS_DETACH 825 */ 826 static APIRET vboxSfOs2Detach(PCSZ pszDev, PVBOXSFVP pVpFsd, PVBOXSFCD pCdFsd, PBYTE pszParam, PUSHORT pcbParam) 827 { 828 /* 829 * Validate the volume data and assocated folder. 830 */ 831 AssertPtrReturn(pVpFsd, ERROR_SYS_INTERNAL); 832 AssertReturn(pVpFsd->u32Magic == VBOXSFVP_MAGIC, ERROR_SYS_INTERNAL); 833 PVBOXSFFOLDER pFolder = pVpFsd->pFolder; 834 AssertPtrReturn(pFolder, ERROR_SYS_INTERNAL); 835 AssertReturn(pFolder->u32Magic == VBOXSFFOLDER_MAGIC, ERROR_SYS_INTERNAL); 836 837 uint8_t idxDrive = UINT8_MAX; 838 if ( pszDev 839 && RT_C_IS_ALPHA(*pszDev)) 840 idxDrive = (*pszDev & ~0x20) - 'A'; 841 842 /* 843 * Can we detach it? 844 */ 845 APIRET rc; 846 KernRequestExclusiveMutex(&g_MtxFolders); 847 if ( pFolder->cOpenFiles == 0 848 && pFolder->cOpenSearches == 0) 849 { 850 /* 851 * Check that we've got the right folder/drive combo. 852 */ 853 if ( idxDrive < RT_ELEMENTS(g_apDriveFolders) 854 && g_apDriveFolders[idxDrive] == pFolder) 855 { 856 g_apDriveFolders[idxDrive] = NULL; 857 uint8_t cDrives = --pFolder->cDrives; 858 AssertMsg(cDrives < 30, ("%#x\n", cDrives)); 859 860 uint32_t cRefs = ASMAtomicDecU32(&pFolder->cRefs); 861 AssertMsg(cRefs < _32K, ("%#x\n", cRefs)); 862 if (cRefs) 863 { 864 /* If there are no zero drives, unlink it from the list and release 865 the list reference. This should almost always drop end up with us 866 destroying the folder.*/ 867 if (cDrives == 0) 868 { 869 RTListNodeRemove(&pFolder->ListEntry); 870 cRefs = ASMAtomicDecU32(&pFolder->cRefs); 871 AssertMsg(cRefs < _32K, ("%#x\n", cRefs)); 872 if (!cRefs) 873 vboxSfOs2DestroyFolder(pFolder); 874 } 875 } 876 else 877 { 878 LogRel(("vboxSfOs2Detach: cRefs=0?!?\n")); 879 vboxSfOs2DestroyFolder(pFolder); 880 } 881 } 882 else 883 { 884 LogRel(("vboxSfOs2Detach: g_apDriveFolders[%#x]=%p pFolder=%p\n", 885 idxDrive, idxDrive < RT_ELEMENTS(g_apDriveFolders) ? g_apDriveFolders[idxDrive] : NULL, pFolder)); 886 rc = ERROR_NOT_SUPPORTED; 887 } 888 } 889 else 890 rc = ERROR_BUSY_DRIVE; 891 KernReleaseExclusiveMutex(&g_MtxFolders); 892 893 RT_NOREF(pszDev, pVpFsd, pCdFsd, pszParam, pcbParam); 894 return rc; 895 } 896 897 898 /** 899 * FS32_ATTACH worker: FSA_ATTACH_INFO 900 */ 901 static APIRET vboxSfOs2QueryAttachInfo(PCSZ pszDev, PVBOXSFVP pVpFsd, PVBOXSFCD pCdFsd, PBYTE pbData, PUSHORT pcbParam) 902 { 903 /* 904 * Userland calls the kernel with a FSQBUFFER buffer, the kernel 905 * fills in the first part of us and hands us &FSQBUFFER::cbFSAData 906 * to do the rest. We could return the share name here, for instance. 907 */ 908 APIRET rc; 909 USHORT cbParam = *pcbParam; 910 if ( pszDev == NULL 911 || (pszDev[0] != '\\' && pszDev[0] != '/')) 912 { 913 /* Validate the volume data and assocated folder. */ 914 AssertPtrReturn(pVpFsd, ERROR_SYS_INTERNAL); 915 AssertReturn(pVpFsd->u32Magic == VBOXSFVP_MAGIC, ERROR_SYS_INTERNAL); 916 PVBOXSFFOLDER pFolder = pVpFsd->pFolder; 917 AssertPtrReturn(pFolder, ERROR_SYS_INTERNAL); 918 AssertReturn(pFolder->u32Magic == VBOXSFFOLDER_MAGIC, ERROR_SYS_INTERNAL); 919 920 /* Try copy out the data. */ 921 if (cbParam >= sizeof(USHORT) + pFolder->cchName + 1) 922 { 923 *pcbParam = (uint16_t)sizeof(USHORT) + pFolder->cchName + 1; 924 cbParam = pFolder->cchName + 1; 925 rc = KernCopyOut(pbData, &cbParam, sizeof(cbParam)); 926 if (rc != NO_ERROR) 927 rc = KernCopyOut(pbData + sizeof(USHORT), pFolder->szName, pFolder->cchName + 1); 928 } 929 else 930 rc = ERROR_BUFFER_OVERFLOW; 931 } 932 else 933 { 934 /* Looks like a device query, so return zero bytes. */ 935 if (cbParam >= sizeof(USHORT)) 936 { 937 *pcbParam = sizeof(USHORT); 938 cbParam = 0; 939 rc = KernCopyOut(pbData, &cbParam, sizeof(cbParam)); 940 } 941 else 942 rc = ERROR_BUFFER_OVERFLOW; 943 } 944 945 RT_NOREF(pCdFsd); 946 return rc; 947 } 948 949 950 DECLASM(APIRET) 951 FS32_ATTACH(ULONG fFlags, PCSZ pszDev, PVBOXSFVP pVpFsd, PVBOXSFCD pCdFsd, PBYTE pszParam, PUSHORT pcbParam) 952 { 953 LogFlow(("FS32_ATTACH: fFlags=%#x pszDev=%p:{%s} pVpFsd=%p pCdFsd=%p pszParam=%p pcbParam=%p\n", 954 fFlags, pszDev, pszDev, pVpFsd, pCdFsd, pszParam, pcbParam)); 955 APIRET rc; 956 if (pVpFsd) 957 { 958 PSHFLSTRING pCleanup = NULL; 959 960 if (fFlags == FS_ATTACH) 961 rc = vboxSfOs2Attach(pszDev, pVpFsd, pCdFsd, pszParam, pcbParam, &pCleanup); 962 else if (fFlags == FSA_DETACH) 963 rc = vboxSfOs2Detach(pszDev, pVpFsd, pCdFsd, pszParam, pcbParam); 964 else if (fFlags == FSA_ATTACH_INFO) 965 rc = vboxSfOs2QueryAttachInfo(pszDev, pVpFsd, pCdFsd, pszParam, pcbParam); 966 else 967 { 968 LogRel(("FS32_ATTACH: Unsupported fFlags value: %#x\n", fFlags)); 969 rc = ERROR_NOT_SUPPORTED; 970 } 971 972 if (pCleanup) 973 vboxSfOs2StrFree(pCleanup); 974 } 975 else 976 rc = ERROR_NOT_SUPPORTED; /* We don't support device attaching. */ 977 LogFlow(("FS32_ATTACH: returns %u\n", rc)); 978 return rc; 979 } 980 981 982 DECLASM(APIRET) 983 FS32_VERIFYUNCNAME(ULONG uType, PCSZ pszName) 984 { 985 LogFlow(("FS32_VERIFYUNCNAME: uType=%#x pszName=%p:{%s}\n", uType, pszName, pszName)); 986 RT_NOREF(uType); /* pass 1 or pass 2 doesn't matter to us, we've only got one 'server'. */ 987 988 if (vboxSfOs2UncPrefixLength(pszName) > 0 ) 989 return NO_ERROR; 62 990 return ERROR_NOT_SUPPORTED; 63 991 } 64 992 65 993 66 DECLASM( int)994 DECLASM(APIRET) 67 995 FS32_FLUSHBUF(USHORT hVPB, ULONG fFlags) 68 996 { … … 72 1000 73 1001 74 DECLASM(int) 75 FS32_FSINFO(ULONG fFlags, USHORT hVPB, PBYTE pbData, USHORT cbData, ULONG uLevel) 76 { 77 NOREF(fFlags); NOREF(hVPB); NOREF(pbData); NOREF(cbData); NOREF(uLevel); 78 return ERROR_NOT_SUPPORTED; 79 } 80 81 82 DECLASM(int) 83 FS32_FSCTL(union argdat *pArgdat, ULONG iArgType, ULONG uFunction, 1002 DECLASM(APIRET) 1003 FS32_FSINFO(ULONG fFlags, USHORT hVpb, PBYTE pbData, ULONG cbData, ULONG uLevel) 1004 { 1005 LogFlow(("FS32_FSINFO: fFlags=%#x hVpb=%#x pbData=%p cbData=%#x uLevel=%p\n", fFlags, hVpb, pbData, cbData, uLevel)); 1006 1007 /* 1008 * Resolve hVpb and do parameter validation. 1009 */ 1010 PVPFSI pVpFsi = NULL; 1011 PVBOXSFVP pVpFsd = Fsh32GetVolParams(hVpb, &pVpFsi); 1012 Log(("FS32_FSINFO: hVpb=%#x -> pVpFsd=%p pVpFsi=%p\n", hVpb, pVpFsd, pVpFsi)); 1013 1014 AssertPtrReturn(pVpFsd, ERROR_SYS_INTERNAL); 1015 AssertReturn(pVpFsd->u32Magic == VBOXSFVP_MAGIC, ERROR_SYS_INTERNAL); 1016 PVBOXSFFOLDER pFolder = pVpFsd->pFolder; /** @todo need to retain it behind locks. */ 1017 AssertPtrReturn(pFolder, ERROR_SYS_INTERNAL); 1018 AssertReturn(pFolder->u32Magic == VBOXSFFOLDER_MAGIC, ERROR_SYS_INTERNAL); 1019 1020 APIRET rc; 1021 1022 /* 1023 * Queries. 1024 */ 1025 if (fFlags == INFO_RETREIVE) 1026 { 1027 /* Check that buffer/level matches up. */ 1028 switch (uLevel) 1029 { 1030 case FSIL_ALLOC: 1031 if (cbData >= sizeof(FSALLOCATE)) 1032 break; 1033 LogFlow(("FS32_FSINOF: cbData=%u < sizeof(FSALLOCATE) -> ERROR_BUFFER_OVERFLOW\n", cbData)); 1034 return ERROR_BUFFER_OVERFLOW; 1035 1036 case FSIL_VOLSER: 1037 if (cbData >= sizeof(FSINFO)) 1038 break; 1039 LogFlow(("FS32_FSINOF: cbData=%u < sizeof(FSINFO) -> ERROR_BUFFER_OVERFLOW\n", cbData)); 1040 return ERROR_BUFFER_OVERFLOW; 1041 1042 default: 1043 LogRel(("FS32_FSINFO: Unsupported info level %u!\n", uLevel)); 1044 return ERROR_INVALID_LEVEL; 1045 } 1046 1047 /* Work buffer union to keep it to a single allocation and no stack. */ 1048 union FsInfoBufs 1049 { 1050 struct 1051 { 1052 SHFLCREATEPARMS Params; 1053 union 1054 { 1055 SHFLSTRING Path; 1056 uint8_t abPadding[SHFLSTRING_HEADER_SIZE + 4]; 1057 }; 1058 } Open; 1059 struct 1060 { 1061 SHFLVOLINFO VolInfo; 1062 union 1063 { 1064 FSALLOCATE Alloc; 1065 FSINFO FsInfo; 1066 }; 1067 } Info; 1068 } *pu = (union FsInfoBufs *)VbglR0PhysHeapAlloc(sizeof(*pu)); 1069 if (!pu) 1070 return ERROR_NOT_ENOUGH_MEMORY; 1071 1072 /* 1073 * To get the info we need to open the root of the folder. 1074 */ 1075 RT_ZERO(pu->Open.Params); 1076 pu->Open.Params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACT_OPEN_IF_EXISTS 1077 | SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ | SHFL_CF_ACCESS_DENYNONE; 1078 pu->Open.Path.u16Size = 3; 1079 pu->Open.Path.u16Length = 2; 1080 pu->Open.Path.String.utf8[0] = '\\'; 1081 pu->Open.Path.String.utf8[1] = '.'; 1082 pu->Open.Path.String.utf8[2] = '\0'; 1083 1084 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, &pu->Open.Path, &pu->Open.Params); 1085 LogFlow(("FS32_FSINFO: VbglR0SfCreate -> %Rrc Result=%d Handle=%#RX64\n", vrc, pu->Open.Params.Result, pu->Open.Params.Handle)); 1086 if ( RT_SUCCESS(vrc) 1087 && pu->Open.Params.Handle != SHFL_HANDLE_NIL) 1088 { 1089 SHFLHANDLE hHandle = pu->Open.Params.Handle; 1090 1091 RT_ZERO(pu->Info.VolInfo); 1092 uint32_t cbBuf = sizeof(pu->Info.VolInfo); 1093 vrc = VbglR0SfFsInfo(&g_SfClient, &pFolder->hHostFolder, hHandle, SHFL_INFO_VOLUME | SHFL_INFO_GET, 1094 &cbBuf, (PSHFLDIRINFO)&pu->Info.VolInfo); 1095 if (RT_SUCCESS(vrc)) 1096 { 1097 /* 1098 * Construct and copy out the requested info. 1099 */ 1100 if (uLevel == FSIL_ALLOC) 1101 { 1102 pu->Info.Alloc.idFileSystem = 0; /* unknown */ 1103 pu->Info.Alloc.cSectorUnit = pu->Info.VolInfo.ulBytesPerAllocationUnit / RT_MAX(pu->Info.VolInfo.ulBytesPerSector, 1); 1104 pu->Info.Alloc.cUnit = (uint32_t)(pu->Info.VolInfo.ullTotalAllocationBytes / RT_MAX(pu->Info.VolInfo.ulBytesPerAllocationUnit, 1)); 1105 pu->Info.Alloc.cUnitAvail = (uint32_t)(pu->Info.VolInfo.ullAvailableAllocationBytes / RT_MAX(pu->Info.VolInfo.ulBytesPerAllocationUnit, 1)); 1106 pu->Info.Alloc.cbSector = (uint16_t)(pu->Info.VolInfo.ulBytesPerSector); 1107 rc = KernCopyOut(pbData, &pu->Info.Alloc, sizeof(pu->Info.Alloc)); 1108 } 1109 else 1110 { 1111 RT_ZERO(pu->Info.FsInfo); 1112 pu->Info.FsInfo.vol.cch = (uint8_t)RT_MIN(pFolder->cchName, sizeof(pu->Info.FsInfo.vol.szVolLabel) - 1); 1113 memcpy(pu->Info.FsInfo.vol.szVolLabel, pFolder->szName, pu->Info.FsInfo.vol.cch); 1114 *(uint32_t *)&pu->Info.FsInfo.fdateCreation = pu->Info.VolInfo.ulSerial; 1115 rc = KernCopyOut(pbData, &pu->Info.FsInfo, sizeof(pu->Info.FsInfo)); 1116 } 1117 } 1118 else 1119 { 1120 LogRel(("FS32_FSINFO: VbglR0SfFsInfo/SHFL_INFO_VOLUME failed: %Rrc\n", rc)); 1121 rc = ERROR_GEN_FAILURE; 1122 } 1123 1124 vrc = VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, hHandle); 1125 AssertRC(vrc); 1126 } 1127 else 1128 rc = ERROR_GEN_FAILURE; 1129 1130 VbglR0PhysHeapFree(pu); 1131 } 1132 /* 1133 * We don't allow setting anything. 1134 */ 1135 else if (fFlags == INFO_SET) 1136 { 1137 LogRel(("FS32_FSINFO: Attempting to set volume info (uLevel=%u, cbData=%#x) -> ERROR_ACCESS_DENIED\n", uLevel, cbData)); 1138 rc = ERROR_ACCESS_DENIED; 1139 } 1140 else 1141 { 1142 LogRel(("FS32_FSINFO: Unknown flags: %#x\n", fFlags)); 1143 rc = ERROR_SYS_INTERNAL; 1144 } 1145 1146 LogFlow(("FS32_FSINFO: returns %#x\n", rc)); 1147 return rc; 1148 } 1149 1150 1151 DECLASM(APIRET) 1152 FS32_FSCTL(union argdat *pArgData, ULONG iArgType, ULONG uFunction, 84 1153 PVOID pvParm, USHORT cbParm, PUSHORT pcbParmIO, 85 1154 PVOID pvData, USHORT cbData, PUSHORT pcbDataIO) 86 1155 { 87 NOREF(pArgdat); NOREF(iArgType); NOREF(uFunction); NOREF(pvParm); NOREF(cbParm); NOREF(pcbParmIO); 1156 LogFlow(("FS32_FSCTL: pArgData=%p iArgType=%#x uFunction=%#x pvParam=%p cbParam=%#x pcbParmIO=%p pvData=%p cbData=%#x pcbDataIO=%p\n", 1157 pArgData, iArgType, uFunction, pvParm, cbParm, pcbParmIO, pvData, cbData, pcbDataIO)); 1158 NOREF(pArgData); NOREF(iArgType); NOREF(uFunction); NOREF(pvParm); NOREF(cbParm); NOREF(pcbParmIO); 88 1159 NOREF(pvData); NOREF(cbData); NOREF(pcbDataIO); 89 1160 return ERROR_NOT_SUPPORTED; … … 91 1162 92 1163 93 DECLASM( int)1164 DECLASM(APIRET) 94 1165 FS32_PROCESSNAME(PSZ pszName) 95 1166 { 1167 LogFlow(("FS32_PROCESSNAME: '%s'\n", pszName)); 96 1168 NOREF(pszName); 97 1169 return NO_ERROR; … … 99 1171 100 1172 101 DECLASM(int) 102 FS32_CHDIR(ULONG fFlags, PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszDir, USHORT iCurDirEnd) 103 { 104 NOREF(fFlags); NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszDir); NOREF(iCurDirEnd); 1173 DECLASM(APIRET) 1174 FS32_CHDIR(ULONG fFlags, PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszDir, LONG offCurDirEnd) 1175 { 1176 LogFlow(("FS32_CHDIR: fFlags=%#x pCdFsi=%p:{%#x,%s} pCdFsd=%p pszDir=%p:{%s} offCurDirEnd=%d\n", 1177 fFlags, pCdFsi, pCdFsi ? pCdFsi->cdi_hVPB : 0xffff, pCdFsi ? pCdFsi->cdi_curdir : "", pCdFsd, pszDir, pszDir, offCurDirEnd)); 1178 1179 /* 1180 * We do not keep any information about open directory, just verify 1181 * them before they are CD'ed into and when asked to revalidate them. 1182 * If there were any path walking benefits, we could consider opening the 1183 * directory and keeping it open, but there isn't, so we don't do that. 1184 */ 1185 APIRET rc = NO_ERROR; 1186 if ( fFlags == CD_EXPLICIT 1187 || fFlags == CD_VERIFY) 1188 { 1189 if (fFlags == CD_VERIFY) 1190 pszDir = pCdFsi->cdi_curdir; 1191 1192 PVBOXSFFOLDER pFolder; 1193 PSHFLSTRING pStrFolderPath; 1194 rc = vboxSfOs2ResolvePath(pszDir, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 1195 if (rc == NO_ERROR) 1196 { 1197 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 1198 if (pParams) 1199 { 1200 RT_ZERO(*pParams); 1201 pParams->CreateFlags = SHFL_CF_LOOKUP; 1202 1203 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 1204 LogFlow(("FS32_CHDIR: VbglR0SfCreate -> %Rrc Result=%d fMode=%#x\n", vrc, pParams->Result, pParams->Info.Attr.fMode)); 1205 if (RT_SUCCESS(vrc)) 1206 { 1207 switch (pParams->Result) 1208 { 1209 case SHFL_FILE_EXISTS: 1210 if (RTFS_IS_DIRECTORY(pParams->Info.Attr.fMode)) 1211 rc = NO_ERROR; 1212 else 1213 rc = ERROR_ACCESS_DENIED; 1214 break; 1215 1216 case SHFL_PATH_NOT_FOUND: 1217 rc = ERROR_PATH_NOT_FOUND; 1218 break; 1219 1220 default: 1221 case SHFL_FILE_NOT_FOUND: 1222 rc = ERROR_FILE_NOT_FOUND; 1223 break; 1224 } 1225 } 1226 else 1227 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_PATH_NOT_FOUND); 1228 VbglR0PhysHeapFree(pParams); 1229 } 1230 else 1231 rc = ERROR_NOT_ENOUGH_MEMORY; 1232 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 1233 } 1234 } 1235 else if (fFlags == CD_FREE) 1236 { 1237 /* nothing to do here. */ 1238 } 1239 else 1240 { 1241 LogRel(("FS32_CHDIR: Unexpected fFlags value: %#x\n", fFlags)); 1242 rc = ERROR_NOT_SUPPORTED; 1243 } 1244 1245 LogFlow(("FS32_CHDIR: returns %u\n", rc)); 1246 return rc; 1247 } 1248 1249 1250 DECLASM(APIRET) 1251 FS32_MKDIR(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszDir, LONG offCurDirEnd, PEAOP pEaOp, ULONG fFlags) 1252 { 1253 LogFlow(("FS32_MKDIR: pCdFsi=%p pCdFsd=%p pszDir=%p:{%s} pEAOp=%p fFlags=%#x\n", pCdFsi, pCdFsd, pszDir, pszDir, offCurDirEnd, pEaOp, fFlags)); 1254 1255 /* 1256 * We don't do EAs. 1257 */ 1258 APIRET rc; 1259 if (pEaOp == NULL) 1260 { 1261 /* 1262 * Resolve the path. 1263 */ 1264 PVBOXSFFOLDER pFolder; 1265 PSHFLSTRING pStrFolderPath; 1266 rc = vboxSfOs2ResolvePath(pszDir, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 1267 if (rc == NO_ERROR) 1268 { 1269 /* 1270 * The silly interface for creating directories amounts an open call that 1271 * fails if it exists and we get a file handle back that needs closing. Sigh. 1272 */ 1273 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 1274 if (pParams != NULL) 1275 { 1276 RT_ZERO(*pParams); 1277 pParams->CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_CREATE_IF_NEW | SHFL_CF_ACT_FAIL_IF_EXISTS 1278 | SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_DENYNONE; 1279 1280 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 1281 LogFlow(("FS32_MKDIR: VbglR0SfCreate -> %Rrc Result=%d fMode=%#x\n", vrc, pParams->Result, pParams->Info.Attr.fMode)); 1282 if (RT_SUCCESS(vrc)) 1283 { 1284 switch (pParams->Result) 1285 { 1286 case SHFL_FILE_CREATED: 1287 if (pParams->Handle != SHFL_HANDLE_NIL) 1288 { 1289 vrc = VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pParams->Handle); 1290 AssertRC(vrc); 1291 } 1292 rc = NO_ERROR; 1293 break; 1294 1295 case SHFL_FILE_EXISTS: 1296 rc = ERROR_ACCESS_DENIED; 1297 break; 1298 1299 case SHFL_PATH_NOT_FOUND: 1300 rc = ERROR_PATH_NOT_FOUND; 1301 break; 1302 1303 default: 1304 case SHFL_FILE_NOT_FOUND: 1305 rc = ERROR_FILE_NOT_FOUND; 1306 break; 1307 } 1308 } 1309 else if (vrc == VERR_ALREADY_EXISTS) 1310 rc = ERROR_ACCESS_DENIED; 1311 else 1312 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_FILE_NOT_FOUND); 1313 VbglR0PhysHeapFree(pParams); 1314 } 1315 else 1316 rc = ERROR_NOT_ENOUGH_MEMORY; 1317 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 1318 } 1319 } 1320 else 1321 { 1322 Log(("FS32_MKDIR: EAs not supported\n")); 1323 rc = ERROR_EAS_NOT_SUPPORTED; 1324 } 1325 1326 RT_NOREF_PV(pCdFsi); 1327 LogFlow(("FS32_RMDIR: returns %u\n", rc)); 1328 return rc; 1329 } 1330 1331 1332 DECLASM(APIRET) 1333 FS32_RMDIR(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszDir, LONG offCurDirEnd) 1334 { 1335 LogFlow(("FS32_RMDIR: pCdFsi=%p pCdFsd=%p pszDir=%p:{%s} offCurDirEnd=%d\n", pCdFsi, pCdFsd, pszDir, pszDir, offCurDirEnd)); 1336 1337 /* 1338 * Resolve the path. 1339 */ 1340 PVBOXSFFOLDER pFolder; 1341 PSHFLSTRING pStrFolderPath; 1342 APIRET rc = vboxSfOs2ResolvePath(pszDir, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 1343 if (rc == NO_ERROR) 1344 { 1345 int vrc = VbglR0SfRemove(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, SHFL_REMOVE_DIR); 1346 LogFlow(("FS32_RMDIR: VbglR0SfRemove -> %Rrc\n", rc)); 1347 if (RT_SUCCESS(vrc)) 1348 rc = NO_ERROR; 1349 else 1350 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_ACCESS_DENIED); 1351 1352 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 1353 } 1354 1355 RT_NOREF_PV(pCdFsi); 1356 LogFlow(("FS32_RMDIR: returns %u\n", rc)); 1357 return rc; 1358 } 1359 1360 1361 DECLASM(APIRET) 1362 FS32_COPY(ULONG fFlags, PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszSrc, LONG offSrcCurDirEnd, 1363 PCSZ pszDst, LONG offDstCurDirEnd, ULONG uNameType) 1364 { 1365 LogFlow(("FS32_COPY: fFlags=%#x pCdFsi=%p pCdFsd=%p pszSrc=%p:{%s} offSrcCurDirEnd=%d pszDst=%p:{%s} offDstCurDirEnd=%d uNameType=%#x\n", 1366 fFlags, pCdFsi, pCdFsd, pszSrc, pszSrc, offSrcCurDirEnd, pszDst, pszDst, offDstCurDirEnd, uNameType)); 1367 NOREF(fFlags); NOREF(pCdFsi); NOREF(pCdFsd); NOREF(pszSrc); NOREF(offSrcCurDirEnd); 1368 NOREF(pszDst); NOREF(offDstCurDirEnd); NOREF(uNameType); 1369 1370 /* Let DOSCALL1.DLL do the work for us till we get a host side function for doing this. */ 1371 return ERROR_CANNOT_COPY; 1372 } 1373 1374 1375 DECLASM(APIRET) 1376 FS32_MOVE(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszSrc, LONG offSrcCurDirEnd, PCSZ pszDst, LONG offDstCurDirEnd, ULONG uNameType) 1377 { 1378 LogFlow(("FS32_MOVE: pCdFsi=%p pCdFsd=%p pszSrc=%p:{%s} offSrcCurDirEnd=%d pszDst=%p:{%s} offDstcurDirEnd=%d uNameType=%#x\n", 1379 pCdFsi, pCdFsd, pszSrc, pszSrc, offSrcCurDirEnd, pszDst, pszDst, offDstCurDirEnd, uNameType)); 1380 1381 /* 1382 * Resolve the source and destination paths and check that they 1383 * refer to the same folder. 1384 */ 1385 PVBOXSFFOLDER pSrcFolder; 1386 PSHFLSTRING pSrcFolderPath; 1387 APIRET rc = vboxSfOs2ResolvePath(pszSrc, pCdFsd, offSrcCurDirEnd, &pSrcFolder, &pSrcFolderPath); 1388 if (rc == NO_ERROR) 1389 { 1390 PVBOXSFFOLDER pDstFolder; 1391 PSHFLSTRING pDstFolderPath; 1392 rc = vboxSfOs2ResolvePath(pszDst, pCdFsd, offDstCurDirEnd, &pDstFolder, &pDstFolderPath); 1393 if (rc == NO_ERROR) 1394 { 1395 if (pSrcFolder == pDstFolder) 1396 { 1397 /* 1398 * Do the renaming. 1399 * Note! Requires 6.0.0beta2+ or 5.2.24+ host for renaming files. 1400 */ 1401 int vrc = VbglR0SfRename(&g_SfClient, &pSrcFolder->hHostFolder, pSrcFolderPath, pDstFolderPath, 1402 SHFL_RENAME_FILE | SHFL_RENAME_DIR); 1403 if (RT_SUCCESS(vrc)) 1404 rc = NO_ERROR; 1405 else 1406 { 1407 Log(("FS32_MOVE: VbglR0SfRename failed: %Rrc\n", rc)); 1408 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_ACCESS_DENIED); 1409 } 1410 } 1411 else 1412 { 1413 Log(("FS32_MOVE: source folder '%s' != destiation folder '%s'\n", pSrcFolder->szName, pDstFolder->szName)); 1414 rc = ERROR_NOT_SAME_DEVICE; 1415 } 1416 vboxSfOs2ReleasePathAndFolder(pDstFolderPath, pDstFolder); 1417 } 1418 vboxSfOs2ReleasePathAndFolder(pSrcFolderPath, pSrcFolder); 1419 } 1420 1421 RT_NOREF_PV(pCdFsi); RT_NOREF_PV(uNameType); 1422 return rc; 1423 } 1424 1425 1426 DECLASM(APIRET) 1427 FS32_DELETE(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszFile, LONG offCurDirEnd) 1428 { 1429 LogFlow(("FS32_DELETE: pCdFsi=%p pCdFsd=%p pszFile=%p:{%s} offCurDirEnd=%d\n", pCdFsi, pCdFsd, pszFile, pszFile, offCurDirEnd)); 1430 1431 /* 1432 * Resolve the path. 1433 */ 1434 PVBOXSFFOLDER pFolder; 1435 PSHFLSTRING pStrFolderPath; 1436 APIRET rc = vboxSfOs2ResolvePath(pszFile, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 1437 if (rc == NO_ERROR) 1438 { 1439 int vrc = VbglR0SfRemove(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, SHFL_REMOVE_FILE); 1440 LogFlow(("FS32_DELETE: VbglR0SfRemove -> %Rrc\n", rc)); 1441 if (RT_SUCCESS(vrc)) 1442 rc = NO_ERROR; 1443 else if (rc == VERR_FILE_NOT_FOUND) 1444 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_ACCESS_DENIED); 1445 1446 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 1447 } 1448 1449 RT_NOREF_PV(pCdFsi); 1450 LogFlow(("FS32_DELETE: returns %u\n", rc)); 1451 return rc; 1452 } 1453 1454 1455 1456 /** 1457 * Worker for FS32_PATHINFO that handles file stat setting. 1458 * 1459 * @returns OS/2 status code 1460 * @param pFolder The folder. 1461 * @param hHostFile The host file handle. 1462 * @param fAttribs The attributes to set. 1463 * @param pTimestamps Pointer to the timestamps. NULL if none should be 1464 * modified. 1465 * @param pObjInfoBuf Buffer to use when setting the attributes (host will 1466 * return current info upon successful return). 1467 */ 1468 APIRET vboxSfOs2SetInfoCommonWorker(PVBOXSFFOLDER pFolder, SHFLHANDLE hHostFile, ULONG fAttribs, 1469 PFILESTATUS pTimestamps, PSHFLFSOBJINFO pObjInfoBuf) 1470 { 1471 /* 1472 * Validate the data a little and convert it to host speak. 1473 * When the date part is zero, the timestamp should not be updated. 1474 */ 1475 RT_ZERO(*pObjInfoBuf); 1476 uint16_t cDelta = vboxSfOs2GetLocalTimeDelta(); 1477 1478 /** @todo should we validate attributes? */ 1479 pObjInfoBuf->Attr.fMode = (fAttribs << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_OS2; 1480 1481 if (pTimestamps) 1482 { 1483 if ( *(uint16_t *)&pTimestamps->fdateCreation != 0 1484 && !vboxSfOs2DateTimeToTimeSpec(pTimestamps->fdateCreation, pTimestamps->ftimeCreation, cDelta, &pObjInfoBuf->BirthTime)) 1485 { 1486 LogRel(("vboxSfOs2SetInfoCommonWorker: Bad creation timestamp: %u-%u-%u %u:%u:%u\n", 1487 pTimestamps->fdateCreation.year + 1980, pTimestamps->fdateCreation.month, pTimestamps->fdateCreation.day, 1488 pTimestamps->ftimeCreation.hours, pTimestamps->ftimeCreation.minutes, pTimestamps->ftimeCreation.twosecs * 2)); 1489 return ERROR_INVALID_PARAMETER; 1490 } 1491 if ( *(uint16_t *)&pTimestamps->fdateLastAccess != 0 1492 && !vboxSfOs2DateTimeToTimeSpec(pTimestamps->fdateLastAccess, pTimestamps->ftimeLastAccess, cDelta, &pObjInfoBuf->AccessTime)) 1493 { 1494 LogRel(("vboxSfOs2SetInfoCommonWorker: Bad last access timestamp: %u-%u-%u %u:%u:%u\n", 1495 pTimestamps->fdateLastAccess.year + 1980, pTimestamps->fdateLastAccess.month, pTimestamps->fdateLastAccess.day, 1496 pTimestamps->ftimeLastAccess.hours, pTimestamps->ftimeLastAccess.minutes, pTimestamps->ftimeLastAccess.twosecs * 2)); 1497 return ERROR_INVALID_PARAMETER; 1498 } 1499 if ( *(uint16_t *)&pTimestamps->fdateLastWrite != 0 1500 && !vboxSfOs2DateTimeToTimeSpec(pTimestamps->fdateLastWrite, pTimestamps->ftimeLastWrite, cDelta, &pObjInfoBuf->ModificationTime)) 1501 { 1502 LogRel(("vboxSfOs2SetInfoCommonWorker: Bad last access timestamp: %u-%u-%u %u:%u:%u\n", 1503 pTimestamps->fdateLastWrite.year + 1980, pTimestamps->fdateLastWrite.month, pTimestamps->fdateLastWrite.day, 1504 pTimestamps->ftimeLastWrite.hours, pTimestamps->ftimeLastWrite.minutes, pTimestamps->ftimeLastWrite.twosecs * 2)); 1505 return ERROR_INVALID_PARAMETER; 1506 } 1507 } 1508 1509 /* 1510 * Call the host to do the updating. 1511 */ 1512 uint32_t cbBuf = sizeof(*pObjInfoBuf); 1513 int vrc = VbglR0SfFsInfo(&g_SfClient, &pFolder->hHostFolder, hHostFile, SHFL_INFO_SET | SHFL_INFO_FILE, 1514 &cbBuf, (SHFLDIRINFO *)pObjInfoBuf); 1515 LogFlow(("vboxSfOs2SetFileInfo: VbglR0SfFsInfo -> %Rrc\n", vrc)); 1516 1517 if (RT_SUCCESS(vrc)) 1518 return NO_ERROR; 1519 return vboxSfOs2ConvertStatusToOs2(vrc, ERROR_ACCESS_DENIED); 1520 } 1521 1522 1523 /** 1524 * Worker for FS32_FILEATTRIBUTE and FS32_PATHINFO that handles setting stuff. 1525 * 1526 * @returns OS/2 status code. 1527 * @param pFolder The folder. 1528 * @param pFolderPath The path within the folder. 1529 * @param fAttribs New file attributes. 1530 * @param pTimestamps New timestamps. May be NULL. 1531 */ 1532 static APIRET vboxSfOs2SetPathInfoWorker(PVBOXSFFOLDER pFolder, PSHFLSTRING pFolderPath, ULONG fAttribs, PFILESTATUS pTimestamps) 1533 1534 { 1535 /* 1536 * In order to do anything we need to open the object. 1537 */ 1538 APIRET rc; 1539 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 1540 if (pParams) 1541 { 1542 RT_ZERO(*pParams); 1543 pParams->CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW 1544 | SHFL_CF_ACCESS_ATTR_READWRITE | SHFL_CF_ACCESS_DENYNONE | SHFL_CF_ACCESS_NONE; 1545 1546 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pFolderPath, pParams); 1547 LogFlow(("vboxSfOs2SetPathInfoWorker: VbglR0SfCreate -> %Rrc Result=%d Handle=%#RX64 fMode=%#x\n", 1548 vrc, pParams->Result, pParams->Handle, pParams->Info.Attr.fMode)); 1549 if ( vrc == VERR_IS_A_DIRECTORY 1550 || ( RT_SUCCESS(vrc) 1551 && pParams->Handle == SHFL_HANDLE_NIL 1552 && RTFS_IS_DIRECTORY(pParams->Info.Attr.fMode))) 1553 { 1554 RT_ZERO(*pParams); 1555 pParams->CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW 1556 | SHFL_CF_ACCESS_ATTR_READWRITE | SHFL_CF_ACCESS_DENYNONE | SHFL_CF_ACCESS_NONE; 1557 vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pFolderPath, pParams); 1558 LogFlow(("vboxSfOs2SetPathInfoWorker: VbglR0SfCreate#2 -> %Rrc Result=%d Handle=%#RX64 fMode=%#x\n", 1559 vrc, pParams->Result, pParams->Handle, pParams->Info.Attr.fMode)); 1560 } 1561 if (RT_SUCCESS(vrc)) 1562 { 1563 switch (pParams->Result) 1564 { 1565 case SHFL_FILE_EXISTS: 1566 if (pParams->Handle != SHFL_HANDLE_NIL) 1567 { 1568 /* 1569 * Join up with FS32_FILEINFO to do the actual setting. 1570 */ 1571 rc = vboxSfOs2SetInfoCommonWorker(pFolder, pParams->Handle, fAttribs, pTimestamps, &pParams->Info); 1572 1573 vrc = VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pParams->Handle); 1574 AssertRC(vrc); 1575 } 1576 else 1577 { 1578 LogRel(("vboxSfOs2SetPathInfoWorker: No handle! fMode=%#x\n", pParams->Info.Attr.fMode)); 1579 rc = ERROR_SYS_INTERNAL; 1580 } 1581 break; 1582 1583 case SHFL_PATH_NOT_FOUND: 1584 rc = ERROR_PATH_NOT_FOUND; 1585 break; 1586 1587 default: 1588 case SHFL_FILE_NOT_FOUND: 1589 rc = ERROR_FILE_NOT_FOUND; 1590 break; 1591 } 1592 } 1593 else 1594 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_FILE_NOT_FOUND); 1595 VbglR0PhysHeapFree(pParams); 1596 } 1597 else 1598 rc = ERROR_NOT_ENOUGH_MEMORY; 1599 return rc; 1600 } 1601 1602 1603 DECLASM(APIRET) 1604 FS32_FILEATTRIBUTE(ULONG fFlags, PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszName, LONG offCurDirEnd, PUSHORT pfAttr) 1605 { 1606 LogFlow(("FS32_FILEATTRIBUTE: fFlags=%#x pCdFsi=%p:{%#x,%s} pCdFsd=%p pszName=%p:{%s} offCurDirEnd=%d pfAttr=%p\n", 1607 fFlags, pCdFsi, pCdFsi->cdi_hVPB, pCdFsi->cdi_curdir, pCdFsd, pszName, pszName, offCurDirEnd, pfAttr)); 1608 RT_NOREF(offCurDirEnd); 1609 1610 APIRET rc; 1611 if ( fFlags == FA_RETRIEVE 1612 || fFlags == FA_SET) 1613 { 1614 PVBOXSFFOLDER pFolder; 1615 PSHFLSTRING pStrFolderPath; 1616 rc = vboxSfOs2ResolvePath(pszName, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 1617 LogRel(("FS32_FILEATTRIBUTE: vboxSfOs2ResolvePath: -> %u pFolder=%p\n", rc, pFolder)); 1618 if (rc == NO_ERROR) 1619 { 1620 if (fFlags == FA_RETRIEVE) 1621 { 1622 /* 1623 * Query it. 1624 */ 1625 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 1626 if (pParams) 1627 { 1628 RT_ZERO(*pParams); 1629 pParams->CreateFlags = SHFL_CF_LOOKUP; 1630 1631 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 1632 LogFlow(("FS32_FILEATTRIBUTE: VbglR0SfCreate -> %Rrc Result=%d fMode=%#x\n", vrc, pParams->Result, pParams->Info.Attr.fMode)); 1633 if (RT_SUCCESS(vrc)) 1634 { 1635 switch (pParams->Result) 1636 { 1637 case SHFL_FILE_EXISTS: 1638 *pfAttr = (uint16_t)((pParams->Info.Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT); 1639 rc = NO_ERROR; 1640 break; 1641 1642 case SHFL_PATH_NOT_FOUND: 1643 rc = ERROR_PATH_NOT_FOUND; 1644 break; 1645 1646 default: 1647 case SHFL_FILE_NOT_FOUND: 1648 rc = ERROR_FILE_NOT_FOUND; 1649 break; 1650 } 1651 } 1652 else 1653 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_FILE_NOT_FOUND); 1654 VbglR0PhysHeapFree(pParams); 1655 } 1656 else 1657 rc = ERROR_NOT_ENOUGH_MEMORY; 1658 } 1659 else 1660 { 1661 /* 1662 * Set the info. Join paths with FS32_PATHINFO. 1663 */ 1664 rc = vboxSfOs2SetPathInfoWorker(pFolder, pStrFolderPath, *pfAttr, NULL); 1665 } 1666 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 1667 } 1668 } 1669 else 1670 { 1671 LogRel(("FS32_FILEATTRIBUTE: Unknwon flag value: %#x\n", fFlags)); 1672 rc = ERROR_NOT_SUPPORTED; 1673 } 1674 LogFlow(("FS32_FILEATTRIBUTE: returns %u\n", rc)); 1675 return rc; 1676 } 1677 1678 1679 /** 1680 * Creates an empty full EA list given a GEALIST and info level. 1681 * 1682 * @returns OS/2 status code. 1683 * @param pEaOp Kernel copy of the EA request with flattened pointers. 1684 * @param uLevel The info level being queried. 1685 * @param pcbWritten Where to return the length of the resulting list. Optional. 1686 * @param poffError User buffer address of EAOP.oError for reporting GEALIST issues. 1687 */ 1688 APIRET vboxSfOs2MakeEmptyEaListEx(PEAOP pEaOp, ULONG uLevel, uint32_t *pcbWritten, ULONG *poffError) 1689 { 1690 ULONG cbDstList; 1691 APIRET rc; 1692 1693 /* 1694 * Levels 8 and 5 are simple. 1695 */ 1696 if ( pEaOp->fpGEAList == NULL 1697 || uLevel == FI_LVL_EAS_FULL_8 1698 || uLevel == FI_LVL_EAS_FULL_5) 1699 { 1700 Log2(("vboxSfOs2MakeEmptyEaList: #1\n")); 1701 cbDstList = RT_UOFFSET_AFTER(FEALIST, cbList); 1702 rc = NO_ERROR; 1703 } 1704 /* 1705 * For levels 3 and 4 we have to do work when a request list is present. 1706 */ 1707 else 1708 { 1709 ULONG cbGetEasLeft = 0; 1710 rc = KernCopyIn(&cbGetEasLeft, &pEaOp->fpGEAList->cbList, sizeof(pEaOp->fpGEAList->cbList)); 1711 ULONG cbFullEasLeft = 0; 1712 if (rc == NO_ERROR) 1713 rc = KernCopyIn(&cbFullEasLeft, &pEaOp->fpFEAList->cbList, sizeof(cbFullEasLeft)); 1714 if ( rc == NO_ERROR 1715 && cbGetEasLeft >= sizeof(pEaOp->fpGEAList->cbList) 1716 && cbFullEasLeft >= sizeof(pEaOp->fpFEAList->cbList)) 1717 { 1718 cbGetEasLeft -= sizeof(pEaOp->fpGEAList->cbList); 1719 cbFullEasLeft -= sizeof(pEaOp->fpFEAList->cbList); 1720 1721 char *pszNameBuf = (char *)RTMemAlloc(256 + 1); 1722 if (!pszNameBuf) 1723 return ERROR_NOT_ENOUGH_MEMORY; 1724 /* Start of no-return zone. */ 1725 1726 uint8_t const *pbSrc = (uint8_t const *)&pEaOp->fpGEAList->list[0]; /* user buffer! */ 1727 uint8_t *pbDst = (uint8_t *)&pEaOp->fpFEAList->list[0]; /* user buffer! */ 1728 Log2(("vboxSfOs2MakeEmptyEaList: %p LB %#x -> %p LB %#x...\n", pbSrc, cbGetEasLeft, pbDst, cbFullEasLeft)); 1729 while (cbGetEasLeft > 0) 1730 { 1731 /* 1732 * pbSrc: GEA: BYTE cbName; char szName[]; 1733 */ 1734 /* Get name length. */ 1735 uint8_t cbName = 0; 1736 rc = KernCopyIn(&cbName, pbSrc, sizeof(cbName)); 1737 Log3(("vboxSfOs2MakeEmptyEaList: cbName=%#x rc=%u\n", cbName, rc)); 1738 if (rc != NO_ERROR) 1739 break; 1740 pbSrc++; 1741 cbGetEasLeft--; 1742 if (cbName + 1 > cbGetEasLeft) 1743 { 1744 cbDstList = pbSrc - 1 - (uint8_t *)pEaOp->fpGEAList; 1745 rc = KernCopyOut(poffError, &cbDstList, sizeof(pEaOp->oError)); 1746 if (rc == NO_ERROR) 1747 rc = ERROR_EA_LIST_INCONSISTENT; 1748 Log(("vboxSfOs2MakeEmptyEaList: ERROR_EA_LIST_INCONSISTENT\n")); 1749 break; 1750 } 1751 1752 /* Copy in name. */ 1753 rc = KernCopyIn(pszNameBuf, pbSrc, cbName + 1); 1754 if (rc != NO_ERROR) 1755 break; 1756 Log3(("vboxSfOs2MakeEmptyEaList: szName: %.*Rhxs\n", cbName + 1, pszNameBuf)); 1757 if ((char *)memchr(pszNameBuf, '\0', cbName) != &pszNameBuf[cbName]) 1758 { 1759 cbDstList = pbSrc - 1 - (uint8_t *)pEaOp->fpGEAList; 1760 rc = KernCopyOut(poffError, &cbDstList, sizeof(pEaOp->oError)); 1761 if (rc == NO_ERROR) 1762 rc = ERROR_INVALID_EA_NAME; 1763 Log(("vboxSfOs2MakeEmptyEaList: ERROR_INVALID_EA_NAME\n")); 1764 break; 1765 } 1766 1767 /* Skip input. */ 1768 cbGetEasLeft -= cbName + 1; 1769 pbSrc += cbName + 1; 1770 1771 /* 1772 * Construct and emit output. 1773 * Note! We should technically skip duplicates here, but who cares... 1774 */ 1775 if (cbName > 0) 1776 { 1777 FEA Result; 1778 if (sizeof(Result) + cbName + 1 > cbFullEasLeft) 1779 { 1780 Log(("vboxSfOs2MakeEmptyEaList: ERROR_BUFFER_OVERFLOW (%#x vs %#x)\n", sizeof(Result) + cbName + 1, cbFullEasLeft)); 1781 rc = ERROR_BUFFER_OVERFLOW; 1782 break; 1783 } 1784 cbFullEasLeft -= sizeof(Result) + cbName + 1; 1785 1786 Result.fEA = 0; 1787 Result.cbName = cbName; 1788 Result.cbValue = 0; 1789 rc = KernCopyOut(pbDst, &Result, sizeof(Result)); 1790 if (rc != NO_ERROR) 1791 break; 1792 pbDst += sizeof(Result); 1793 1794 rc = KernCopyOut(pbDst, pszNameBuf, cbName + 1); 1795 if (rc != NO_ERROR) 1796 break; 1797 pbDst += cbName + 1; 1798 } 1799 } /* (while more GEAs) */ 1800 1801 /* End of no-return zone. */ 1802 RTMemFree(pszNameBuf); 1803 1804 cbDstList = (uintptr_t)pbDst - (uintptr_t)pEaOp->fpFEAList; 1805 } 1806 else 1807 { 1808 if (rc == NO_ERROR) 1809 rc = ERROR_BUFFER_OVERFLOW; 1810 cbDstList = 0; /* oh, shut up. */ 1811 } 1812 1813 } 1814 1815 /* Set the list length. */ 1816 if (rc == NO_ERROR) 1817 rc = KernCopyOut(&pEaOp->fpFEAList->cbList, &cbDstList, sizeof(pEaOp->fpFEAList->cbList)); 1818 1819 if (pcbWritten) 1820 *pcbWritten = cbDstList; 1821 1822 Log(("vboxSfOs2MakeEmptyEaList: return %u (cbDstList=%#x)\n", rc, cbDstList)); 1823 return rc; 1824 } 1825 1826 1827 1828 /** 1829 * Creates an empty full EA list given a GEALIST and info level. 1830 * 1831 * @returns OS/2 status code. 1832 * @param pEaOp The EA request. User buffer. 1833 * @param uLevel The info level being queried. 1834 */ 1835 DECL_NO_INLINE(RT_NOTHING, APIRET) 1836 vboxSfOs2MakeEmptyEaList(PEAOP pEaOp, ULONG uLevel) 1837 { 1838 /* 1839 * Copy the user request into memory, do pointer conversion, and 1840 * join extended function version. 1841 */ 1842 EAOP EaOp = { NULL, NULL, 0 }; 1843 APIRET rc = KernCopyIn(&EaOp, pEaOp, sizeof(EaOp)); 1844 if (rc == NO_ERROR) 1845 { 1846 Log2(("vboxSfOs2MakeEmptyEaList: #0: %p %p %#x\n", EaOp.fpGEAList, EaOp.fpFEAList, EaOp.oError)); 1847 EaOp.fpFEAList = (PFEALIST)KernSelToFlat((uintptr_t)EaOp.fpFEAList); 1848 EaOp.fpGEAList = (PGEALIST)KernSelToFlat((uintptr_t)EaOp.fpGEAList); 1849 Log2(("vboxSfOs2MakeEmptyEaList: #0b: %p %p\n", EaOp.fpGEAList, EaOp.fpFEAList)); 1850 1851 rc = vboxSfOs2MakeEmptyEaListEx(&EaOp, uLevel, NULL, &pEaOp->oError); 1852 } 1853 return rc; 1854 } 1855 1856 1857 /** 1858 * Corrects the case of the given path. 1859 * 1860 * @returns OS/2 status code 1861 * @param pFolder The folder. 1862 * @param pStrFolderPath The path within the folder. 1863 * @param pszPath The original path for figuring the drive letter or 1864 * UNC part of the path. 1865 * @param pbData Where to return the data (user address). 1866 * @param cbData The maximum amount of data we can return. 1867 */ 1868 static int vboxSfOs2QueryCorrectCase(PVBOXSFFOLDER pFolder, PSHFLSTRING pStrFolderPath, const char *pszPath, 1869 PBYTE pbData, ULONG cbData) 1870 { 1871 /** @todo do case correction. Can do step-by-step dir info... but slow */ 1872 RT_NOREF(pFolder, pStrFolderPath, pszPath, pbData, cbData); 105 1873 return ERROR_NOT_SUPPORTED; 106 1874 } 107 1875 108 1876 109 DECLASM(int) 110 FS32_MKDIR(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszDir, USHORT iCurDirEnd, 111 PBYTE pbEABuf, ULONG fFlags) 112 { 113 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszDir); NOREF(iCurDirEnd); NOREF(pbEABuf); NOREF(fFlags); 1877 /** 1878 * Copy out file status info. 1879 * 1880 * @returns OS/2 status code. 1881 * @param pbDst User address to put the status info at. 1882 * @param cbDst The size of the structure to produce. 1883 * @param uLevel The info level of the structure to produce. 1884 * @param pSrc The shared folder FS object info source structure. 1885 * @note Careful with stack, thus no-inlining. 1886 */ 1887 DECL_NO_INLINE(RT_NOTHING, APIRET) 1888 vboxSfOs2FileStatusFromObjInfo(PBYTE pbDst, ULONG cbDst, ULONG uLevel, SHFLFSOBJINFO const *pSrc) 1889 { 1890 union 1891 { 1892 FILESTATUS Fst; 1893 FILESTATUS2 Fst2; 1894 FILESTATUS3L Fst3L; 1895 FILESTATUS4L Fst4L; 1896 } uTmp; 1897 1898 int16_t cMinLocalTimeDelta = vboxSfOs2GetLocalTimeDelta(); 1899 vboxSfOs2DateTimeFromTimeSpec(&uTmp.Fst.fdateCreation, &uTmp.Fst.ftimeCreation, pSrc->BirthTime, cMinLocalTimeDelta); 1900 vboxSfOs2DateTimeFromTimeSpec(&uTmp.Fst.fdateLastAccess, &uTmp.Fst.ftimeLastAccess, pSrc->AccessTime, cMinLocalTimeDelta); 1901 vboxSfOs2DateTimeFromTimeSpec(&uTmp.Fst.fdateLastWrite, &uTmp.Fst.ftimeLastWrite, pSrc->ModificationTime, cMinLocalTimeDelta); 1902 if (uLevel < FI_LVL_STANDARD_64) 1903 { 1904 uTmp.Fst.cbFile = (uint32_t)RT_MIN(pSrc->cbObject, UINT32_MAX); 1905 uTmp.Fst.cbFileAlloc = (uint32_t)RT_MIN(pSrc->cbAllocated, UINT32_MAX); 1906 uTmp.Fst.attrFile = (uint16_t)((pSrc->Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT); 1907 if (uLevel == FI_LVL_STANDARD_EASIZE) 1908 uTmp.Fst2.cbList = 0; 1909 } 1910 else 1911 { 1912 uTmp.Fst3L.cbFile = pSrc->cbObject; 1913 uTmp.Fst3L.cbFileAlloc = pSrc->cbAllocated; 1914 uTmp.Fst3L.attrFile = (pSrc->Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT; 1915 uTmp.Fst4L.cbList = 0; 1916 } 1917 1918 return KernCopyOut(pbDst, &uTmp, cbDst); 1919 } 1920 1921 1922 1923 /** 1924 * Worker for FS32_PATHINFO that handles file stat queries. 1925 * 1926 * @returns OS/2 status code 1927 * @param pFolder The folder. 1928 * @param pStrFolderPath The path within the folder. 1929 * @param uLevel The information level. 1930 * @param pbData Where to return the data (user address). 1931 * @param cbData The amount of data to produce. 1932 */ 1933 static APIRET vboxSfOs2QueryPathInfo(PVBOXSFFOLDER pFolder, PSHFLSTRING pStrFolderPath, ULONG uLevel, PBYTE pbData, ULONG cbData) 1934 { 1935 APIRET rc; 1936 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 1937 if (pParams) 1938 { 1939 RT_ZERO(*pParams); 1940 pParams->CreateFlags = SHFL_CF_LOOKUP; 1941 1942 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 1943 LogFlow(("FS32_PATHINFO: VbglR0SfCreate -> %Rrc Result=%d fMode=%#x\n", vrc, pParams->Result, pParams->Info.Attr.fMode)); 1944 if (RT_SUCCESS(vrc)) 1945 { 1946 switch (pParams->Result) 1947 { 1948 case SHFL_FILE_EXISTS: 1949 switch (uLevel) 1950 { 1951 /* 1952 * Produce the desired file stat data. 1953 */ 1954 case FI_LVL_STANDARD: 1955 case FI_LVL_STANDARD_EASIZE: 1956 case FI_LVL_STANDARD_64: 1957 case FI_LVL_STANDARD_EASIZE_64: 1958 rc = vboxSfOs2FileStatusFromObjInfo(pbData, cbData, uLevel, &pParams->Info); 1959 break; 1960 1961 /* 1962 * We don't do EAs and we "just" need to return no-EAs. 1963 * However, that's not as easy as you might think. 1964 */ 1965 case FI_LVL_EAS_FROM_LIST: 1966 case FI_LVL_EAS_FULL: 1967 case FI_LVL_EAS_FULL_5: 1968 case FI_LVL_EAS_FULL_8: 1969 rc = vboxSfOs2MakeEmptyEaList((PEAOP)pbData, uLevel); 1970 break; 1971 1972 default: 1973 AssertFailed(); 1974 rc = ERROR_GEN_FAILURE; 1975 break; 1976 } 1977 break; 1978 1979 case SHFL_PATH_NOT_FOUND: 1980 rc = ERROR_PATH_NOT_FOUND; 1981 break; 1982 1983 default: 1984 case SHFL_FILE_NOT_FOUND: 1985 rc = ERROR_FILE_NOT_FOUND; 1986 break; 1987 } 1988 } 1989 else 1990 rc = vboxSfOs2ConvertStatusToOs2(rc, ERROR_FILE_NOT_FOUND); 1991 VbglR0PhysHeapFree(pParams); 1992 } 1993 else 1994 rc = ERROR_NOT_ENOUGH_MEMORY; 1995 return rc; 1996 } 1997 1998 1999 DECLASM(APIRET) 2000 FS32_PATHINFO(USHORT fFlags, PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszPath, LONG offCurDirEnd, 2001 ULONG uLevel, PBYTE pbData, ULONG cbData) 2002 { 2003 LogFlow(("FS32_PATHINFO: fFlags=%#x pCdFsi=%p:{%#x,%s} pCdFsd=%p pszPath=%p:{%s} offCurDirEnd=%d uLevel=%u pbData=%p cbData=%#x\n", 2004 fFlags, pCdFsi, pCdFsi->cdi_hVPB, pCdFsi->cdi_curdir, pCdFsd, pszPath, pszPath, offCurDirEnd, uLevel, pbData, cbData)); 2005 2006 /* 2007 * Check the level. 2008 * 2009 * Note! You would think this is FIL_STANDARD, FIL_QUERYEASIZE, 2010 * FIL_QUERYEASFROMLISTL and such. However, there are several levels 2011 * (4/14, 6/16, 7/17, 8/18) that are not defined in os2.h and then 2012 * there and FIL_QUERYFULLNAME that is used very between the kernel 2013 * and the FSD so the kernel can implement DosEnumAttributes. 2014 * 2015 * Note! DOSCALL1.DLL has code for converting FILESTATUS to FILESTATUS3 2016 * and FILESTATUS2 to FILESTATUS4 as needed. We don't need to do this. 2017 * It also has weird code for doubling the FILESTATUS2.cbList value 2018 * for no apparent reason. 2019 */ 2020 ULONG cbMinData; 2021 switch (uLevel) 2022 { 2023 case FI_LVL_STANDARD: 2024 cbMinData = sizeof(FILESTATUS); 2025 AssertCompileSize(FILESTATUS, 0x16); 2026 break; 2027 case FI_LVL_STANDARD_64: 2028 cbMinData = sizeof(FILESTATUS3L); 2029 AssertCompileSize(FILESTATUS3L, 0x20); /* cbFile and cbFileAlloc are misaligned. */ 2030 break; 2031 case FI_LVL_STANDARD_EASIZE: 2032 cbMinData = sizeof(FILESTATUS2); 2033 AssertCompileSize(FILESTATUS2, 0x1a); 2034 break; 2035 case FI_LVL_STANDARD_EASIZE_64: 2036 cbMinData = sizeof(FILESTATUS4L); 2037 AssertCompileSize(FILESTATUS4L, 0x24); /* cbFile and cbFileAlloc are misaligned. */ 2038 break; 2039 case FI_LVL_EAS_FROM_LIST: 2040 case FI_LVL_EAS_FULL: 2041 case FI_LVL_EAS_FULL_5: 2042 case FI_LVL_EAS_FULL_8: 2043 cbMinData = sizeof(EAOP); 2044 break; 2045 case FI_LVL_VERIFY_PATH: 2046 case FI_LVL_CASE_CORRECT_PATH: 2047 cbMinData = 1; 2048 break; 2049 default: 2050 LogRel(("FS32_PATHINFO: Unsupported info level %u!\n", uLevel)); 2051 return ERROR_INVALID_LEVEL; 2052 } 2053 if (cbData < cbMinData || pbData == NULL) 2054 { 2055 Log(("FS32_PATHINFO: ERROR_BUFFER_OVERFLOW (cbMinData=%#x, cbData=%#x, pszPath=%s)\n", cbMinData, cbData, pszPath)); 2056 return ERROR_BUFFER_OVERFLOW; 2057 } 2058 2059 /* 2060 * Resolve the path to a folder and folder path. 2061 */ 2062 PVBOXSFFOLDER pFolder; 2063 PSHFLSTRING pStrFolderPath; 2064 APIRET rc = vboxSfOs2ResolvePath(pszPath, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 2065 LogFlow(("FS32_PATHINFO: vboxSfOs2ResolvePath: -> %u pFolder=%p\n", rc, pFolder)); 2066 if (rc == NO_ERROR) 2067 { 2068 /* 2069 * Query information. 2070 */ 2071 if (fFlags == PI_RETRIEVE) 2072 { 2073 if ( uLevel != FI_LVL_VERIFY_PATH 2074 && uLevel != FI_LVL_CASE_CORRECT_PATH) 2075 rc = vboxSfOs2QueryPathInfo(pFolder, pStrFolderPath, uLevel, pbData, cbMinData); 2076 else if (uLevel == FI_LVL_VERIFY_PATH) 2077 rc = NO_ERROR; /* vboxSfOs2ResolvePath should've taken care of this already */ 2078 else 2079 rc = vboxSfOs2QueryCorrectCase(pFolder, pStrFolderPath, pszPath, pbData, cbData); 2080 } 2081 /* 2082 * Update information. 2083 */ 2084 else if ( fFlags == PI_SET 2085 || fFlags == (PI_SET | PI_WRITE_THRU)) 2086 { 2087 if ( uLevel == FI_LVL_STANDARD 2088 || uLevel == FI_LVL_STANDARD_64) 2089 { 2090 /* Read in the data and join paths with FS32_FILEATTRIBUTE: */ 2091 PFILESTATUS pDataCopy = (PFILESTATUS)VbglR0PhysHeapAlloc(cbMinData); 2092 if (pDataCopy) 2093 { 2094 rc = KernCopyIn(pDataCopy, pbData, cbMinData); 2095 if (rc == NO_ERROR) 2096 rc = vboxSfOs2SetPathInfoWorker(pFolder, pStrFolderPath, 2097 uLevel == FI_LVL_STANDARD 2098 ? (ULONG)pDataCopy->attrFile 2099 : ((PFILESTATUS3L)pDataCopy)->attrFile, 2100 (PFILESTATUS)pDataCopy); 2101 VbglR0PhysHeapFree(pDataCopy); 2102 } 2103 else 2104 rc = ERROR_NOT_ENOUGH_MEMORY; 2105 } 2106 else if (uLevel == FI_LVL_STANDARD_EASIZE) 2107 rc = ERROR_EAS_NOT_SUPPORTED; 2108 else 2109 rc = ERROR_INVALID_LEVEL; 2110 } 2111 else 2112 { 2113 LogRel(("FS32_PATHINFO: Unknown flags value: %#x (path: %s)\n", fFlags, pszPath)); 2114 rc = ERROR_INVALID_PARAMETER; 2115 } 2116 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 2117 } 2118 RT_NOREF_PV(pCdFsi); 2119 return rc; 2120 } 2121 2122 2123 DECLASM(APIRET) 2124 FS32_MOUNT(USHORT fFlags, PVPFSI pvpfsi, PVBOXSFVP pVpFsd, USHORT hVPB, PCSZ pszBoot) 2125 { 2126 NOREF(fFlags); NOREF(pvpfsi); NOREF(pVpFsd); NOREF(hVPB); NOREF(pszBoot); 114 2127 return ERROR_NOT_SUPPORTED; 115 2128 } 116 2129 117 118 DECLASM(int)119 FS32_RMDIR(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszDir, USHORT iCurDirEnd)120 {121 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszDir); NOREF(iCurDirEnd);122 return ERROR_NOT_SUPPORTED;123 }124 125 126 DECLASM(int)127 FS32_COPY(USHORT fFlags, PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszSrc, USHORT iSrcCurDirEnd,128 PCSZ pszDst, USHORT iDstCurDirEnd, USHORT uNameType)129 {130 NOREF(fFlags); NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszSrc); NOREF(iSrcCurDirEnd);131 NOREF(pszDst); NOREF(iDstCurDirEnd); NOREF(uNameType);132 return ERROR_NOT_SUPPORTED;133 }134 135 136 DECLASM(int)137 FS32_MOVE(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszSrc, USHORT iSrcCurDirEnd,138 PCSZ pszDst, USHORT iDstCurDirEnd, USHORT uNameType)139 {140 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszSrc); NOREF(iSrcCurDirEnd); NOREF(pszDst); NOREF(iDstCurDirEnd); NOREF(uNameType);141 return ERROR_NOT_SUPPORTED;142 }143 144 145 DECLASM(int)146 FS32_DELETE(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszFile, USHORT iCurDirEnd)147 {148 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszFile); NOREF(iCurDirEnd);149 return ERROR_NOT_SUPPORTED;150 }151 152 153 DECLASM(int)154 FS32_FILEATTRIBUTE(ULONG fFlags, PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszName, USHORT iCurDirEnd, PUSHORT pfAttr)155 {156 NOREF(fFlags); NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszName); NOREF(iCurDirEnd); NOREF(pfAttr);157 return ERROR_NOT_SUPPORTED;158 }159 160 161 DECLASM(int)162 FS32_PATHINFO(USHORT fFlags, PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszName, USHORT iCurDirEnd,163 USHORT uLevel, PBYTE pbData, USHORT cbData)164 {165 NOREF(fFlags); NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszName); NOREF(iCurDirEnd); NOREF(uLevel); NOREF(pbData); NOREF(cbData);166 return ERROR_NOT_SUPPORTED;167 }168 169 170 DECLASM(int)171 FS32_MOUNT(USHORT fFlags, PVPFSI pvpfsi, PVBOXSFVP pvpfsd, USHORT hVPB, PCSZ pszBoot)172 {173 NOREF(fFlags); NOREF(pvpfsi); NOREF(pvpfsd); NOREF(hVPB); NOREF(pszBoot);174 return ERROR_NOT_SUPPORTED;175 }176 -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSF.def
r69339 r75337 85 85 FS_SETSWAP 86 86 FS_SHUTDOWN 87 FS_VERIFYUNCNAME 87 88 FS_WRITE 88 89 89 90 ; 32-bit entry points. 90 FS32_CHGFILEPTR91 91 FS32_CHGFILEPTRL 92 92 FS32_READ -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFA.asm
r69339 r75337 30 30 31 31 32 ;******************************************************************************* 33 ;* Header Files*34 ;******************************************************************************* 32 ;********************************************************************************************************************************* 33 ;* Header Files * 34 ;********************************************************************************************************************************* 35 35 %define RT_INCL_16BIT_SEGMENTS 36 36 %include "iprt/asmdefs.mac" 37 37 %include "iprt/err.mac" 38 %include "iprt/x86.mac" 39 %include "iprt/formats/dwarf.mac" 38 40 %include "VBox/VBoxGuest.mac" 39 41 40 42 41 ;******************************************************************************* 42 ;* Defined Constants And Macros * 43 ;******************************************************************************* 43 ;********************************************************************************************************************************* 44 ;* Dwarf constants and macros * 45 ;********************************************************************************************************************************* 46 ;; enable dwarf debug info 47 %define WITH_DWARF 1 48 49 ;; Emits a LEB128 (signed) constant (%1) - limited range. 50 %macro DWARF_LEB128 1 51 %if %1 >= 0 52 %if %1 < 64 53 db %1 54 %else 55 db (%1 & 0x7f) | 0x80 56 db (%1 >> 7) & 0x7f 57 %endif 58 %else 59 %if %1 > -64 60 db (%1 & 0x3f) | 0x40 61 %else 62 db (%1 & 0x7f) | 0x80 63 db ((%1 >> 7) & 0x7f) | 0x40 64 %endif 65 %endif 66 %endmacro 67 68 ;; Emits a ULEB128 (unsigned) constant (%1) - limited range. 69 %macro DWARF_ULEB128 1 70 %if %1 < 0x80 71 db %1 72 %elif %1 < 0x4000 73 db (%1 & 0x7f) | 0x80 74 db (%1 >> 7) 75 %elif %1 < 0x200000 76 db ((%1) & 0x7f) | 0x80 77 db ((%1 >> 7) & 0x7f) | 0x80 78 db ((%1 >> 14)) 79 %else 80 %error out of range: %1 81 %endif 82 %endmacro 83 84 ;; Emits a pair of ULEB128 constants. Useful for .debug_abbrev. 85 %macro DWARF_ULEB128_PAIR 2 86 DWARF_ULEB128 %1 87 DWARF_ULEB128 %2 88 %endmacro 89 90 91 ;; defines a CFA offset by register (%1) + unsigned offset (%2). 92 %macro CFA_DEF_CFA 2 93 db DW_CFA_def_cfa 94 DWARF_ULEB128 %1 95 DWARF_ULEB128 %2 96 %endmacro 97 98 ;; defines the register (%1) value as CFA + unsigned offset (%2) * data_alignment_factor. 99 %macro CFA_VAL_OFFSET 2 100 db DW_CFA_val_offset 101 DWARF_ULEB128 %1 102 DWARF_ULEB128 %2 103 %endmacro 104 105 ;; defines the register (%1) save location as CFA + unsigned offset (%2) * data_alignment_factor. 106 %macro CFA_OFFSET 2 107 %if %1 < 0x40 108 db DW_CFA_offset | %1 109 %else 110 db DW_CFA_offset_extended 111 DWARF_ULEB128 %1 112 %endif 113 DWARF_ULEB128 %2 114 %endmacro 115 116 %define MY_ABBREV_CODE_CU 2 117 %define MY_ABBREV_CODE_LABEL 3 118 119 120 ;; Emits a debug info for a label in CODE16. 121 ;; @param %1 symbol 122 %macro DWARF_LABEL_CODE16 1 123 %ifdef WITH_DWARF 124 segment _debug_info 125 DWARF_ULEB128 MY_ABBREV_CODE_LABEL 126 dd %1 wrt CODE16 127 db 2 ; Hardcoded CODE16 number. 128 %defstr tmp_str_conversion %1 129 db tmp_str_conversion, 0 130 %endif 131 segment CODE16 132 %endmacro 133 134 135 ;; Emits a debug info for a label in CODE32. 136 ;; @param %1 symbol 137 %macro DWARF_LABEL_TEXT32 1 138 %ifdef WITH_DWARF 139 segment _debug_info 140 DWARF_ULEB128 MY_ABBREV_CODE_LABEL 141 dd %1 wrt TEXT32 142 db 3 ; Hardcoded TEXT32 number. 143 %defstr tmp_str_conversion %1 144 db tmp_str_conversion, 0 145 %endif 146 segment TEXT32 147 %endmacro 148 149 150 151 ;********************************************************************************************************************************* 152 ;* Additional Segment definitions. * 153 ;********************************************************************************************************************************* 154 %ifdef WITH_DWARF ; We need to use '_debug_xxx' + dotseg.exe here rather than '.debug_xxx' because some nasm crap. 155 segment _debug_frame public CLASS=DWARF align=4 use32 156 g_cie_thunk_back: 157 dd (g_cie_thunk_end - g_cie_thunk_back - 4) ; Length 158 dd 0xffffffff ; I'm a CIE. 159 db 4 ; DwARF v4 160 db 0 ; Augmentation. 161 db 4 ; Address size. 162 db 4 ; Segment size. 163 DWARF_LEB128 1 ; Code alignment factor. 164 DWARF_LEB128 -1 ; Data alignment factor. 165 DWARF_ULEB128 DWREG_X86_RA ; Return register column. 166 CFA_DEF_CFA DWREG_X86_EBP, 8 ; cfa = EBP + 8 167 CFA_OFFSET DWREG_X86_EBP, 8 ; EBP = [CFA - 8] 168 CFA_OFFSET DWREG_X86_ESP, 8+10 ; SS = [CFA - 8 - 10] 169 CFA_OFFSET DWREG_X86_SS, 8+6 ; SS = [CFA - 8 - 6] 170 CFA_OFFSET DWREG_X86_ES, 8+4 ; ES = [CFA - 8 - 4] 171 CFA_OFFSET DWREG_X86_DS, 8+2 ; DS = [CFA - 8 - 2] 172 CFA_OFFSET DWREG_X86_CS, 2 ; CS = [CFA - 2] 173 ; CFA_OFFSET DWREG_X86_RA, 4 ; RetAddr = [CFA - 4] 174 align 4, db DW_CFA_nop 175 g_cie_thunk_end: 176 177 178 segment _debug_abbrev public CLASS=DWARF align=1 use32 179 g_abbrev_compile_unit: 180 DWARF_ULEB128 MY_ABBREV_CODE_CU 181 DWARF_ULEB128_PAIR DW_TAG_compile_unit, DW_CHILDREN_yes 182 DWARF_ULEB128_PAIR DW_AT_name, DW_FORM_string 183 db 0, 0 ; the end. 184 g_abbrev_label: 185 db MY_ABBREV_CODE_LABEL 186 DWARF_ULEB128_PAIR DW_TAG_label, DW_CHILDREN_no 187 DWARF_ULEB128_PAIR DW_AT_low_pc, DW_FORM_addr 188 DWARF_ULEB128_PAIR DW_AT_segment, DW_FORM_data1 189 DWARF_ULEB128_PAIR DW_AT_name, DW_FORM_string 190 db 0, 0 ; the end. 191 192 193 segment _debug_info public CLASS=DWARF align=1 use32 194 g_dwarf_compile_unit_header: 195 dd g_dwarf_compile_unit_end - g_dwarf_compile_unit_header - 4 196 dw 2 ; DWARF v2 197 dd g_abbrev_compile_unit wrt _debug_abbrev 198 db 4 ; address_size 199 .compile_unit_die: 200 db MY_ABBREV_CODE_CU 201 db __FILE__, 0 202 203 segment TEXT32 204 %endif ; WITH_DWARF 205 206 207 208 ;********************************************************************************************************************************* 209 ;* Defined Constants And Macros * 210 ;********************************************************************************************************************************* 44 211 %define ERROR_NOT_SUPPORTED 50 45 212 %define ERROR_INVALID_PARAMETER 87 46 213 %define DevHlp_AttachDD 2ah 214 47 215 48 216 ;; … … 53 221 %%my_dbg_str: db %1, 0ah, 0 54 222 segment CODE16 55 push ax56 mov ax, %%my_dbg_str57 call NAME(dbgstr16)58 pop ax223 push ax 224 mov ax, %%my_dbg_str 225 call NAME(dbgstr16) 226 pop ax 59 227 %endif 60 228 %endmacro 61 229 230 ;%define RT_STR_QUOTE " 231 ;%define RT_STR(a_Label) RT_STR_QUOTE a_Label RT_STR_QUOTE 62 232 63 233 %macro VBOXSF_EP16_BEGIN 2 234 DWARF_LABEL_CODE16 %1 64 235 global %1 65 236 %1: 66 DEBUG_STR16 {'VBoxSF: ', %2}237 ;DEBUG_STR16 {'VBoxSF: ', %2} 67 238 68 239 %endmacro … … 74 245 75 246 ;; 76 ; Used totaking us to 32-bit and reserving a parameter frame.247 ; Used in a 16-bit entrypoint for taking us to 32-bit and reserving a parameter frame. 77 248 ; 78 249 ; @param %1 The function name … … 80 251 ; 81 252 %macro VBOXSF_TO_32 2 82 ; prologue 83 push ebp 84 mov ebp, esp ; bp 85 push ds ; bp - 2 86 push es ; bp - 4 87 88 ; Reserve the 32-bit parameter and align the stack on a 16 byte 89 ; boundary to make GCC really happy. 90 sub sp, %2 91 and sp, 0fff0h 92 93 ;jmp far dword NAME(%i %+ _32) wrt FLAT 94 db 066h 95 db 0eah 96 dd NAME(%1 %+ _32) ;wrt FLAT 97 dw TEXT32 wrt FLAT 253 ; prologue 254 %ifdef DEBUG 255 %ifndef WITH_DWARF 256 inc ebp 257 %endif 258 %endif 259 push ebp 260 mov ebp, esp ; bp 261 push ds ; bp - 2 262 push es ; bp - 4 263 %ifdef WITH_DWARF 264 push ss ; bp - 6 265 lea eax, [esp + 3*2 + 4 + 4] ; bp - 10: return esp (16-bit) 266 push eax 267 %endif 268 269 ; Reserve the 32-bit parameter and align the stack on a 16 byte 270 ; boundary to make GCC really happy. 271 sub sp, %2 272 and sp, 0fff0h 273 274 ;jmp far dword NAME(%i %+ _32) wrt FLAT 275 db 066h 276 db 0eah 277 dd NAME(%1 %+ _32) ;wrt FLAT 278 dw TEXT32 wrt FLAT 98 279 segment TEXT32 99 280 GLOBALNAME %1 %+ _32 100 mov ax, DATA32 wrt FLAT 101 mov ds, ax 102 mov es, ax 103 104 call KernThunkStackTo32 105 106 %endmacro VBOXSF_TO_32 1 281 DWARF_LABEL_TEXT32 NAME(%1 %+ _32) 282 mov ax, DATA32 wrt FLAT 283 mov ds, ax 284 mov es, ax 285 286 call KernThunkStackTo32 287 .vboxsf_to_32_end: 288 289 %endmacro ; VBOXSF_TO_32 107 290 108 291 ;; … … 112 295 ; 113 296 %macro VBOXSF_TO_16 1 114 push eax 115 call KernThunkStackTo16 116 pop eax 117 118 ;jmp far dword NAME(%1 %+ _16) wrt CODE16 119 db 066h 120 db 0eah 121 dw NAME(%1 %+ _16) wrt CODE16 122 dw CODE16 297 .vboxsf_to_16_start: 298 push eax 299 call KernThunkStackTo16 300 pop eax 301 302 ;jmp far dword NAME(%1 %+ _16) wrt CODE16 303 db 066h 304 db 0eah 305 dw NAME(%1 %+ _16) wrt CODE16 306 dw CODE16 307 .vboxsf_to_16_done_32: 308 %ifdef WITH_DWARF 309 segment _debug_frame 310 .fde_start: 311 dd (.fde_end - .fde_start) - 4 312 dd g_cie_thunk_back wrt _debug_frame 313 dd 2 ; TEXT32 idx 314 dd NAME(%1 %+ _32) wrt TEXT32 315 dd .vboxsf_to_16_done_32 - NAME(%1 %+ _32) 316 db DW_CFA_advance_loc | 4 317 db DW_CFA_advance_loc | 2 318 db DW_CFA_advance_loc | 2 319 db DW_CFA_advance_loc | 5 320 db DW_CFA_advance_loc2 ; Hack to easily cover the parameter conversion code. 321 dw .vboxsf_to_16_start - .vboxsf_to_32_end 322 db DW_CFA_advance_loc | 1 323 db DW_CFA_advance_loc | 5 324 db DW_CFA_advance_loc | 1 325 db DW_CFA_advance_loc | 6 326 align 4, db DW_CFA_nop 327 .fde_end: 328 %endif ; WITH_DWARF 123 329 segment CODE16 124 330 GLOBALNAME %1 %+ _16 125 126 ; Epilogue 127 lea sp, [bp - 4h] 128 pop es 129 pop ds 130 mov esp, ebp 131 pop ebp 331 DWARF_LABEL_CODE16 NAME(%1 %+ _16) 332 333 ; Epilogue 334 lea sp, [bp - 4h] 335 pop es 336 pop ds 337 mov esp, ebp 338 pop ebp 339 %ifdef DEBUG 340 %ifndef WITH_DWARF 341 dec ebp 342 %endif 343 %endif 132 344 %endmacro 133 345 134 346 ;; 135 ; Thunks the given 16:16 pointer to a flat pointer .136 ; 137 ; @param %1 The negatedebp offset of the input.347 ; Thunks the given 16:16 pointer to a flat pointer, NULL is returned as NULL. 348 ; 349 ; @param %1 The ebp offset of the input. 138 350 ; @param %2 The esp offset of the output. 139 351 ; @users eax, edx, ecx 140 352 ; 141 353 %macro VBOXSF_FARPTR_2_FLAT 2 142 movzx eax, word [ebp - (%1) + 2] 143 push eax 144 call KernSelToFlat 145 movzx edx, word [ebp - (%1)] 146 add eax, edx 147 mov [esp + (%2)], eax 354 push dword [ebp + (%1)] 355 call KernSelToFlat 356 add esp, 4h 357 mov [esp + (%2)], eax 148 358 %endmacro 149 359 … … 151 361 ; Thunks the given 16:16 struct sffsd pointer to a flat pointer. 152 362 ; 153 ; @param %1 The negatedebp offset of the input.363 ; @param %1 The ebp offset of the input. 154 364 ; @param %2 The esp offset of the output. 155 365 ; @users eax, ecx 156 366 ; 157 367 %macro VBOXSF_PSFFSD_2_FLAT 2 158 lds cx, [ebp - (%1)] 159 and ecx, 0ffffh 160 mov eax, dword [ecx] 161 mov cx, DATA32 wrt FLAT 162 mov [esp + (%2)], eax 163 mov ds, cx 368 %if 1 ; optimize later if we can. 369 VBOXSF_FARPTR_2_FLAT %1, %2 370 %else 371 lds cx, [ebp + (%1)] 372 and ecx, 0ffffh 373 mov eax, dword [ecx] 374 mov cx, DATA32 wrt FLAT 375 mov [esp + (%2)], eax 376 mov ds, cx 377 %endif 164 378 %endmacro 165 379 … … 168 382 ; Thunks the given 16:16 struct cdfsd pointer to a flat pointer. 169 383 ; 170 ; @param %1 The negatedebp offset of the input.384 ; @param %1 The ebp offset of the input. 171 385 ; @param %2 The esp offset of the output. 172 386 ; @users eax, ecx 173 387 ; 174 388 %macro VBOXSF_PCDFSD_2_FLAT 2 175 lds cx, [ebp - (%1)] 176 and ecx, 0ffffh 177 mov eax, dword [ecx] 178 mov cx, DATA32 wrt FLAT 179 mov [esp + (%2)], eax 180 mov ds, cx 389 %if 1 ; optimize later if possible. 390 VBOXSF_FARPTR_2_FLAT %1, %2 391 %else 392 lds cx, [ebp + (%1)] 393 and ecx, 0ffffh 394 mov eax, dword [ecx] 395 mov cx, DATA32 wrt FLAT 396 mov [esp + (%2)], eax 397 mov ds, cx 398 %endif 181 399 %endmacro 182 400 … … 184 402 ; Thunks the given 16:16 struct fsfsd pointer to a flat pointer. 185 403 ; 186 ; @param %1 The negatedebp offset of the input.404 ; @param %1 The ebp offset of the input. 187 405 ; @param %2 The esp offset of the output. 188 406 ; @users eax, ecx 189 407 ; 190 408 %macro VBOXSF_PFSFSD_2_FLAT 2 191 lds cx, [ebp - (%1)] 192 and ecx, 0ffffh 193 mov eax, dword [ecx] 194 mov cx, DATA32 wrt FLAT 195 mov [esp + (%2)], eax 196 mov ds, cx 409 %if 1 ; optimize later if possible. 410 VBOXSF_FARPTR_2_FLAT %1, %2 411 %else 412 lds cx, [ebp + (%1)] 413 and ecx, 0ffffh 414 mov eax, dword [ecx] 415 mov cx, DATA32 wrt FLAT 416 mov [esp + (%2)], eax 417 mov ds, cx 418 %endif 197 419 %endmacro 198 420 199 421 200 201 ;******************************************************************************* 202 ;* External Symbols * 203 ;******************************************************************************* 422 ;; 423 ; Used for taking us from 32-bit and reserving a parameter frame. 424 ; 425 ; @param %1 The function name 426 ; @param %2 The number of bytes to reserve 427 ; 428 %macro VBOXSF_FROM_32 2 429 ; prologue 430 push ebp 431 mov ebp, esp ; ebp 432 push ds ; ebp - 4 433 push es ; ebp - 8 434 push ebx ; ebp - 0ch 435 push esi ; ebp - 10h 436 push edi ; ebp - 14h 437 438 ; Reserve the 32-bit parameter 439 sub esp, %2 440 441 call KernThunkStackTo16 442 443 ;jmp far dword NAME(%1 %+ _16) wrt CODE16 444 db 066h 445 db 0eah 446 dw NAME(%1 %+ _16) wrt CODE16 447 dw CODE16 448 .vboxsf_from_32_end: 449 450 segment CODE16 451 GLOBALNAME %1 %+ _16 452 DWARF_LABEL_CODE16 NAME(%1 %+ _16) 453 454 %endmacro 455 456 457 ;; 458 ; Partially countering VBOXSF_FROM_32: 459 ; Take us back to 32-bit mode, but don't do the epilogue stuff. 460 ; 461 ; @param %1 The function name 462 ; 463 %macro VBOXSF_FROM_16_SWITCH 1 464 .vboxsf_from_16_start: 465 ;jmp far dword NAME(%i %+ _32) wrt FLAT 466 db 066h 467 db 0eah 468 dd NAME(%1 %+ _32) ;wrt FLAT 469 dw TEXT32 wrt FLAT 470 .vboxsf_from_16_done_16: 471 472 segment TEXT32 473 GLOBALNAME %1 %+ _32 474 DWARF_LABEL_TEXT32 NAME(%1 %+ _32) 475 476 push eax 477 call KernThunkStackTo32 478 mov ax, DATA32 wrt FLAT 479 mov ds, eax 480 mov es, eax 481 pop eax 482 %endmacro 483 484 485 ;; 486 ; Does the remaining recovery after VBOXSF_FROM_32. 487 ; 488 %macro VBOXSF_FROM_16_EPILOGUE 0 489 ; Epilogue 490 lea esp, [ebp - 14h] 491 pop edi 492 pop esi 493 pop ebx 494 pop es 495 pop ds 496 cld 497 mov esp, ebp 498 pop ebp 499 %endmacro 500 501 502 503 504 ;********************************************************************************************************************************* 505 ;* External Symbols * 506 ;********************************************************************************************************************************* 204 507 segment CODE32 205 508 extern KernThunkStackTo32 … … 208 511 segment CODE16 209 512 extern FSH_FORCENOSWAP 513 extern FSH_GETVOLPARM 210 514 extern DOS16WRITE 211 515 … … 252 556 extern NAME(FS32_SETSWAP) 253 557 extern NAME(FS32_SHUTDOWN) 558 extern NAME(FS32_VERIFYUNCNAME) 254 559 extern FS32_WRITE 255 560 … … 267 572 global FS_NAME 268 573 FS_NAME: 269 db 'VBOXSF',0574 db 'VBOXSF',0 270 575 271 576 ;; … … 284 589 FS_ATTRIBUTE: 285 590 FS32_ATTRIBUTE: 286 dd FSA_REMOTE + FSA_LARGEFILE ;+ FSA_LVL7+ FSA_LOCK591 dd FSA_REMOTE + FSA_LARGEFILE + FSA_UNC + FSA_LVL7 ;+ FSA_LOCK 287 592 288 593 ;; 64-bit mask. … … 291 596 global FS_MPSAFEFLAGS2 292 597 FS_MPSAFEFLAGS2: 293 dd 0294 dd 0598 dd 1 | (1<<6) 599 dd 0 295 600 296 601 ;; 297 602 ; Set after VBoxSFR0Init16Bit has been called. 298 603 GLOBALNAME g_fDoneRing0 299 db 0604 db 0 300 605 301 606 align 4 … … 304 609 ; (This is set by FS_INIT.) 305 610 GLOBALNAME g_fpfnDevHlp 306 dd 0611 dd 0 307 612 308 613 ;; 309 614 ; Whether initialization should be verbose or quiet. 310 615 GLOBALNAME g_fVerbose 311 db 1616 db 1 312 617 313 618 ;; DEBUGGING DEBUGGING 314 619 GLOBALNAME g_u32Info 315 dd 0620 dd 0 316 621 317 622 ;; Far pointer to DOS16WRITE (corrected set before called). 318 623 ; Just a 'temporary' hack to work around a wlink/nasm issue. 319 624 GLOBALNAME g_fpfnDos16Write 320 dw DOS16WRITE321 dw seg DOS16WRITE625 dw DOS16WRITE 626 dw seg DOS16WRITE 322 627 323 628 ;; 324 629 ; The attach dd data. 325 630 GLOBALNAME g_VBoxGuestAttachDD 326 dd 0327 dw 0328 dd 0329 dw 0631 dd 0 632 dw 0 633 dd 0 634 dw 0 330 635 ;; 331 636 ; The AttachDD name of the VBoxGuest.sys driver. 332 637 GLOBALNAME g_szVBoxGuestName 333 db VBOXGUEST_DEVICE_NAME_SHORT, 0638 db VBOXGUEST_DEVICE_NAME_SHORT, 0 334 639 ;; 335 640 ; The VBoxGuest IDC connection data. 336 641 GLOBALNAME g_VBoxGuestIDC 337 times VBGLOS2ATTACHDD_size db 0642 times VBGLOS2ATTACHDD_size db 0 338 643 339 644 ;; … … 341 646 segment DATA32 342 647 g_pfnDos16Write: 343 dd DOS16WRITE ; flat648 dd DOS16WRITE ; flat 344 649 345 650 … … 363 668 VBOXSF_EP16_BEGIN FS_ALLOCATEPAGESPACE, 'FS_ALLOCATEPAGESPACE' 364 669 VBOXSF_TO_32 FS_ALLOCATEPAGESPACE, 4*4 365 movzx ecx, word [ebp + 08h] ; cbWantContig366 mov [esp + 3*4], ecx367 mov edx, [ebp + 0ah] ; cb368 mov [esp + 2*4], edx369 VBOXSF_PSFFSD_2_FLAT 0eh, 1*4 ; psffsd370 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; psffsi371 call NAME(FS32_ALLOCATEPAGESPACE)670 movzx ecx, word [ebp + 08h] ; cbWantContig 671 mov [esp + 3*4], ecx 672 mov edx, [ebp + 0ah] ; cb 673 mov [esp + 2*4], edx 674 VBOXSF_PSFFSD_2_FLAT 0eh, 1*4 ; psffsd 675 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; psffsi 676 call NAME(FS32_ALLOCATEPAGESPACE) 372 677 VBOXSF_TO_16 FS_ALLOCATEPAGESPACE 373 retf 0eh678 retf 0eh 374 679 VBOXSF_EP16_END FS_ALLOCATEPAGESPACE 375 680 … … 378 683 ; 379 684 VBOXSF_EP16_BEGIN FS_ATTACH, 'FS_ATTACH' 380 ;381 ; Initialized ring-0 yet? (this is a likely first entry point)382 ;383 push ds384 mov ax, DATA16385 mov ds, ax386 test byte [NAME(g_fDoneRing0)], 1387 jnz .DoneRing0388 call NAME(VBoxSFR0Init16Bit)685 ; 686 ; Initialized ring-0 yet? (this is a likely first entry point) 687 ; 688 push ds 689 mov ax, DATA16 690 mov ds, ax 691 test byte [NAME(g_fDoneRing0)], 1 692 jnz .DoneRing0 693 call NAME(VBoxSFR0Init16Bit) 389 694 .DoneRing0: 390 pop ds695 pop ds 391 696 392 697 VBOXSF_TO_32 FS_ATTACH, 6*4 393 VBOXSF_FARPTR_2_FLAT 08h, 5*4 ; pcbParm394 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pszParm395 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pcdfsd396 VBOXSF_FARPTR_2_FLAT 14h, 2*4 ; pvpfsd397 VBOXSF_FARPTR_2_FLAT 18h, 1*4 ; pszDev398 movzx ecx, word [ebp + 1ch] ; fFlag399 mov [esp], ecx400 call NAME(FS32_ATTACH)698 VBOXSF_FARPTR_2_FLAT 08h, 5*4 ; pcbParm 699 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pszParm 700 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pcdfsd 701 VBOXSF_FARPTR_2_FLAT 14h, 2*4 ; pvpfsd 702 VBOXSF_FARPTR_2_FLAT 18h, 1*4 ; pszDev 703 movzx ecx, word [ebp + 1ch] ; fFlag 704 mov [esp], ecx 705 call NAME(FS32_ATTACH) 401 706 VBOXSF_TO_16 FS_ATTACH 402 retf 16h707 retf 16h 403 708 VBOXSF_EP16_END FS_ATTACH 404 709 … … 408 713 VBOXSF_EP16_BEGIN FS_CANCELLOCKREQUEST, 'FS_CANCELLOCKREQUEST' 409 714 VBOXSF_TO_32 FS_CANCELLOCKREQUEST, 3*4 410 VBOXSF_FARPTR_2_FLAT 08h, 2*4 ; pLockRange411 VBOXSF_PSFFSD_2_FLAT 0ch, 1*4 ; psffsd412 VBOXSF_FARPTR_2_FLAT 10h, 0*4 ; psffsi413 call NAME(FS32_CANCELLOCKREQUEST)715 VBOXSF_FARPTR_2_FLAT 08h, 2*4 ; pLockRange 716 VBOXSF_PSFFSD_2_FLAT 0ch, 1*4 ; psffsd 717 VBOXSF_FARPTR_2_FLAT 10h, 0*4 ; psffsi 718 call NAME(FS32_CANCELLOCKREQUEST) 414 719 VBOXSF_TO_16 FS_CANCELLOCKREQUEST 415 retf 0ch720 retf 0ch 416 721 VBOXSF_EP16_END FS_CANCELLOCKREQUEST 417 722 … … 421 726 VBOXSF_EP16_BEGIN FS_CANCELLOCKREQUESTL, 'FS_CANCELLOCKREQUESTL' 422 727 VBOXSF_TO_32 FS_CANCELLOCKREQUESTL, 3*4 423 VBOXSF_FARPTR_2_FLAT 08h, 2*4 ; pLockRange424 VBOXSF_PSFFSD_2_FLAT 0ch, 1*4 ; psffsd425 VBOXSF_FARPTR_2_FLAT 10h, 0*4 ; psffsi426 call NAME(FS32_CANCELLOCKREQUESTL)728 VBOXSF_FARPTR_2_FLAT 08h, 2*4 ; pLockRange 729 VBOXSF_PSFFSD_2_FLAT 0ch, 1*4 ; psffsd 730 VBOXSF_FARPTR_2_FLAT 10h, 0*4 ; psffsi 731 call NAME(FS32_CANCELLOCKREQUESTL) 427 732 VBOXSF_TO_16 FS_CANCELLOCKREQUESTL 428 retf 0ch733 retf 0ch 429 734 VBOXSF_EP16_END FS_CANCELLOCKREQUESTL 430 735 … … 434 739 VBOXSF_EP16_BEGIN FS_CHDIR, 'FS_CHDIR' 435 740 VBOXSF_TO_32 FS_CHDIR, 5*4 436 movzx ecx, word [ebp + 08h] ; iCurDirEnd437 mov [esp + 4*4], ecx438 VBOXSF_FARPTR_2_FLAT 0ah, 3*4 ; pszDir439 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pcdfsd (use slow thunk here, see flag)440 VBOXSF_FARPTR_2_FLAT 12h, 1*4 ; pcdfsi441 movzx eax, word [ebp + 16h] ; flag442 mov [esp], eax443 call NAME(FS32_CHDIR)741 movsx ecx, word [ebp + 08h] ; iCurDirEnd 742 mov [esp + 4*4], ecx 743 VBOXSF_FARPTR_2_FLAT 0ah, 3*4 ; pszDir 744 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pcdfsd (use slow thunk here, see flag) 745 VBOXSF_FARPTR_2_FLAT 12h, 1*4 ; pcdfsi 746 movzx eax, word [ebp + 16h] ; flag 747 mov [esp], eax 748 call NAME(FS32_CHDIR) 444 749 VBOXSF_TO_16 FS_CHDIR 445 retf 10h750 retf 10h 446 751 VBOXSF_EP16_END FS_CHDIR 447 752 … … 450 755 VBOXSF_EP16_BEGIN FS_CHGFILEPTR, 'FS_CHGFILEPTR' 451 756 VBOXSF_TO_32 FS_CHGFILEPTR, 6*4 452 movzx ecx, word [ebp + 08h] ; IOflag453 mov [esp + 5*4], ecx454 movzx edx, word [ebp + 0ah] ; usMethod455 mov [esp + 4*4], edx456 mov eax, [ebp + 0ch] ; off457 mov [esp + 2*4], eax458 rol eax, 1 ; high dword - is there a better way than this?459 and eax, 1460 mov edx, 0ffffffffh461 mul edx462 mov [esp + 3*4], eax463 VBOXSF_PSFFSD_2_FLAT 10h, 1*4 ; psffsd464 VBOXSF_FARPTR_2_FLAT 14h, 0*4 ; psffsi465 call FS32_CHGFILEPTRL757 movzx ecx, word [ebp + 08h] ; IOflag 758 mov [esp + 5*4], ecx 759 movzx edx, word [ebp + 0ah] ; usMethod 760 mov [esp + 4*4], edx 761 mov eax, [ebp + 0ch] ; off 762 mov [esp + 2*4], eax 763 rol eax, 1 ; high dword - is there a better way than this? 764 and eax, 1 765 mov edx, 0ffffffffh 766 mul edx 767 mov [esp + 3*4], eax 768 VBOXSF_PSFFSD_2_FLAT 10h, 1*4 ; psffsd 769 VBOXSF_FARPTR_2_FLAT 14h, 0*4 ; psffsi 770 call FS32_CHGFILEPTRL 466 771 VBOXSF_TO_16 FS_CHGFILEPTR 467 retf 10h772 retf 10h 468 773 VBOXSF_EP16_END FS_CHGFILEPTR 469 774 … … 474 779 VBOXSF_EP16_BEGIN FS_CLOSE, 'FS_CLOSE' 475 780 VBOXSF_TO_32 FS_CLOSE, 4*4 476 VBOXSF_PSFFSD_2_FLAT 08h, 3*4 ; psffsd477 VBOXSF_FARPTR_2_FLAT 0ch, 2*4 ; psffsi478 movzx ecx, word [ebp + 10h] ; IOflag479 mov [esp + 1*4], ecx480 movzx edx, word [ebp + 12h] ; type481 mov [esp], edx482 call NAME(FS32_CLOSE)781 VBOXSF_PSFFSD_2_FLAT 08h, 3*4 ; psffsd 782 VBOXSF_FARPTR_2_FLAT 0ch, 2*4 ; psffsi 783 movzx ecx, word [ebp + 10h] ; IOflag 784 mov [esp + 1*4], ecx 785 movzx edx, word [ebp + 12h] ; type 786 mov [esp], edx 787 call NAME(FS32_CLOSE) 483 788 VBOXSF_TO_16 FS_CLOSE 484 retf 0ch789 retf 0ch 485 790 VBOXSF_EP16_END FS_CLOSE 486 791 … … 491 796 VBOXSF_EP16_BEGIN FS_COMMIT, 'FS_COMMIT' 492 797 VBOXSF_TO_32 FS_COMMIT, 4*4 493 VBOXSF_PSFFSD_2_FLAT 08h, 3*4 ; psffsd494 VBOXSF_FARPTR_2_FLAT 0ch, 2*4 ; psffsi495 movzx ecx, word [ebp + 10h] ; IOflag496 mov [esp + 1*4], ecx497 movzx edx, word [ebp + 12h] ; type498 mov [esp], edx499 call NAME(FS32_COMMIT)798 VBOXSF_PSFFSD_2_FLAT 08h, 3*4 ; psffsd 799 VBOXSF_FARPTR_2_FLAT 0ch, 2*4 ; psffsi 800 movzx ecx, word [ebp + 10h] ; IOflag 801 mov [esp + 1*4], ecx 802 movzx edx, word [ebp + 12h] ; type 803 mov [esp], edx 804 call NAME(FS32_COMMIT) 500 805 VBOXSF_TO_16 FS_COMMIT 501 retf 0ch806 retf 0ch 502 807 VBOXSF_EP16_END FS_COMMIT 503 808 … … 507 812 VBOXSF_EP16_BEGIN FS_COPY, 'FS_COPY' 508 813 VBOXSF_TO_32 FS_COPY, 8*4 509 movzx ecx, word [ebp + 08h] ; flag510 mov [esp + 7*4], ecx511 movzx edx, word [ebp + 0ah] ; iDstCurDirEnd512 mov [esp + 6*4], edx513 VBOXSF_FARPTR_2_FLAT 0ch, 5*4 ; pszDst514 movzx eax, word [ebp + 10h] ; iSrcCurDirEnd515 mov [esp + 4*4], eax516 VBOXSF_FARPTR_2_FLAT 12h, 3*4 ; pszSrc517 VBOXSF_PCDFSD_2_FLAT 16h, 2*4 ; psffsd518 VBOXSF_FARPTR_2_FLAT 1ah, 1*4 ; psffsi519 movzx ecx, word [ebp + 1eh] ; flag520 mov [esp], ecx521 call NAME(FS32_COPY)814 movzx ecx, word [ebp + 08h] ; flag 815 mov [esp + 7*4], ecx 816 movsx edx, word [ebp + 0ah] ; iDstCurDirEnd 817 mov [esp + 6*4], edx 818 VBOXSF_FARPTR_2_FLAT 0ch, 5*4 ; pszDst 819 movsx eax, word [ebp + 10h] ; iSrcCurDirEnd 820 mov [esp + 4*4], eax 821 VBOXSF_FARPTR_2_FLAT 12h, 3*4 ; pszSrc 822 VBOXSF_PCDFSD_2_FLAT 16h, 2*4 ; psffsd 823 VBOXSF_FARPTR_2_FLAT 1ah, 1*4 ; psffsi 824 movzx ecx, word [ebp + 1eh] ; flag 825 mov [esp], ecx 826 call NAME(FS32_COPY) 522 827 VBOXSF_TO_16 FS_COPY 523 retf 18h828 retf 18h 524 829 VBOXSF_EP16_END FS_COPY 525 830 … … 529 834 VBOXSF_EP16_BEGIN FS_DELETE, 'FS_DELETE' 530 835 VBOXSF_TO_32 FS_DELETE, 4*4 531 movzx ecx, word [ebp + 08h] ; iCurDirEnd532 mov [esp + 3*4], ecx533 VBOXSF_FARPTR_2_FLAT 0ah, 2*4 ; pszFile534 VBOXSF_PCDFSD_2_FLAT 0eh, 1*4 ; pcdfsd535 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; pcdfsi536 call NAME(FS32_DELETE)836 movsx ecx, word [ebp + 08h] ; iCurDirEnd 837 mov [esp + 3*4], ecx 838 VBOXSF_FARPTR_2_FLAT 0ah, 2*4 ; pszFile 839 VBOXSF_PCDFSD_2_FLAT 0eh, 1*4 ; pcdfsd 840 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; pcdfsi 841 call NAME(FS32_DELETE) 537 842 VBOXSF_TO_16 FS_DELETE 538 retf 0eh843 retf 0eh 539 844 VBOXSF_EP16_END FS_DELETE 540 845 … … 544 849 VBOXSF_EP16_BEGIN FS_DOPAGEIO, 'FS_DOPAGEIO' 545 850 VBOXSF_TO_32 FS_DOPAGEIO, 3*4 546 VBOXSF_FARPTR_2_FLAT 08h, 2*4 ; pList547 VBOXSF_PSFFSD_2_FLAT 0ch, 1*4 ; psffsd548 VBOXSF_FARPTR_2_FLAT 10h, 0*4 ; psffsi549 call NAME(FS32_DOPAGEIO)851 VBOXSF_FARPTR_2_FLAT 08h, 2*4 ; pList 852 VBOXSF_PSFFSD_2_FLAT 0ch, 1*4 ; psffsd 853 VBOXSF_FARPTR_2_FLAT 10h, 0*4 ; psffsi 854 call NAME(FS32_DOPAGEIO) 550 855 VBOXSF_TO_16 FS_DOPAGEIO 551 retf 0ch856 retf 0ch 552 857 VBOXSF_EP16_END FS_DOPAGEIO 553 858 … … 555 860 ; @cproto void FS_EXIT(USHORT uid, USHORT pid, USHORT pdb) 556 861 VBOXSF_EP16_BEGIN FS_EXIT, 'FS_EXIT' 557 ;558 ; Initialized ring-0 yet? (this is a likely first entry point)559 ;560 push ds561 mov ax, DATA16562 mov ds, ax563 test byte [NAME(g_fDoneRing0)], 1564 jnz .DoneRing0565 call NAME(VBoxSFR0Init16Bit)862 ; 863 ; Initialized ring-0 yet? (this is a likely first entry point) 864 ; 865 push ds 866 mov ax, DATA16 867 mov ds, ax 868 test byte [NAME(g_fDoneRing0)], 1 869 jnz .DoneRing0 870 call NAME(VBoxSFR0Init16Bit) 566 871 .DoneRing0: 567 pop ds872 pop ds 568 873 569 874 VBOXSF_TO_32 FS_EXIT, 3*4 570 movzx ecx, word [ebp + 08h] ; pdb571 mov [esp + 2*4], ecx572 movzx edx, word [ebp + 0ah] ; pib573 mov [esp + 1*4], edx574 movzx eax, word [ebp + 0ch] ; uid575 mov [esp], eax576 call NAME(FS32_EXIT)875 movzx ecx, word [ebp + 08h] ; pdb 876 mov [esp + 2*4], ecx 877 movzx edx, word [ebp + 0ah] ; pib 878 mov [esp + 1*4], edx 879 movzx eax, word [ebp + 0ch] ; uid 880 mov [esp], eax 881 call NAME(FS32_EXIT) 577 882 VBOXSF_TO_16 FS_EXIT 578 retf 6h883 retf 6h 579 884 VBOXSF_EP16_END FS_EXIT 580 885 … … 585 890 VBOXSF_EP16_BEGIN FS_FILEATTRIBUTE, 'FS_FILEATTRIBUTE' 586 891 VBOXSF_TO_32 FS_FILEATTRIBUTE, 6*4 587 VBOXSF_FARPTR_2_FLAT 08h, 5*4 ; pAttr588 movzx ecx, word [ebp + 0ch] ; iCurDirEnd589 mov [esp + 4*4], ecx590 VBOXSF_FARPTR_2_FLAT 0eh, 3*4 ; pszName591 VBOXSF_PCDFSD_2_FLAT 12h, 2*4 ; pcdfsd592 VBOXSF_FARPTR_2_FLAT 16h, 1*4 ; pcdfsi593 movzx edx, word [ebp + 1ah] ; flag594 mov [esp], edx595 call NAME(FS32_FILEATTRIBUTE)892 VBOXSF_FARPTR_2_FLAT 08h, 5*4 ; pAttr 893 movsx ecx, word [ebp + 0ch] ; iCurDirEnd - caller may pass 0xffff, so sign extend. 894 mov [esp + 4*4], ecx 895 VBOXSF_FARPTR_2_FLAT 0eh, 3*4 ; pszName 896 VBOXSF_PCDFSD_2_FLAT 12h, 2*4 ; pcdfsd 897 VBOXSF_FARPTR_2_FLAT 16h, 1*4 ; pcdfsi 898 movzx edx, word [ebp + 1ah] ; flag 899 mov [esp], edx 900 call NAME(FS32_FILEATTRIBUTE) 596 901 VBOXSF_TO_16 FS_FILEATTRIBUTE 597 retf 14h902 retf 14h 598 903 VBOXSF_EP16_END FS_FILEATTRIBUTE 599 904 … … 604 909 VBOXSF_EP16_BEGIN FS_FILEINFO, 'FS_FILEINFO' 605 910 VBOXSF_TO_32 FS_FILEINFO, 7*4 606 movzx ecx, word [ebp + 08h] ; IOflag607 mov [esp + 6*4], ecx608 movzx edx, word [ebp + 0ah] ; cbData609 mov [esp + 5*4], edx610 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pData611 movzx eax, word [ebp + 10h] ; level612 mov [esp + 3*4], eax613 VBOXSF_PSFFSD_2_FLAT 12h, 2*4 ; psffsd614 VBOXSF_FARPTR_2_FLAT 16h, 1*4 ; psffsi615 movzx ecx, word [ebp + 1ah] ; flag616 mov [esp], ecx617 call NAME(FS32_FILEINFO)911 movzx ecx, word [ebp + 08h] ; IOflag 912 mov [esp + 6*4], ecx 913 movzx edx, word [ebp + 0ah] ; cbData 914 mov [esp + 5*4], edx 915 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pData 916 movzx eax, word [ebp + 10h] ; level 917 mov [esp + 3*4], eax 918 VBOXSF_PSFFSD_2_FLAT 12h, 2*4 ; psffsd 919 VBOXSF_FARPTR_2_FLAT 16h, 1*4 ; psffsi 920 movzx ecx, word [ebp + 1ah] ; flag 921 mov [esp], ecx 922 call NAME(FS32_FILEINFO) 618 923 VBOXSF_TO_16 FS_FILEINFO 619 retf 14h924 retf 14h 620 925 VBOXSF_EP16_END FS_FILEINFO 621 926 … … 626 931 VBOXSF_EP16_BEGIN FS_FILEIO, 'FS_FILEIO' 627 932 VBOXSF_TO_32 FS_FILEIO, 6*4 628 movzx ecx, word [ebp + 08h] ; IOFlag629 mov [esp + 5*4], ecx630 VBOXSF_FARPTR_2_FLAT 0ah, 4*4 ; poError631 movzx edx, word [ebp + 0eh] ; cbCmdList632 mov [esp + 3*4], edx633 VBOXSF_FARPTR_2_FLAT 10h, 2*4 ; pCmdList634 VBOXSF_PSFFSD_2_FLAT 14h, 1*4 ; psffsd635 VBOXSF_FARPTR_2_FLAT 18h, 0*4 ; psffsi636 call NAME(FS32_FILEIO)933 movzx ecx, word [ebp + 08h] ; IOFlag 934 mov [esp + 5*4], ecx 935 VBOXSF_FARPTR_2_FLAT 0ah, 4*4 ; poError 936 movzx edx, word [ebp + 0eh] ; cbCmdList 937 mov [esp + 3*4], edx 938 VBOXSF_FARPTR_2_FLAT 10h, 2*4 ; pCmdList 939 VBOXSF_PSFFSD_2_FLAT 14h, 1*4 ; psffsd 940 VBOXSF_FARPTR_2_FLAT 18h, 0*4 ; psffsi 941 call NAME(FS32_FILEIO) 637 942 VBOXSF_TO_16 FS_FILEIO 638 retf 14h943 retf 14h 639 944 VBOXSF_EP16_END FS_FILEIO 640 945 … … 645 950 VBOXSF_EP16_BEGIN FS_FILELOCKS, 'FS_FILELOCKS' 646 951 VBOXSF_TO_32 FS_FILELOCKS, 6*4 647 mov ecx, [ebp + 08h] ; flags648 mov [esp + 5*4], ecx649 mov edx, [ebp + 0ch] ; timeout650 mov [esp + 4*4], edx651 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pLockRange652 VBOXSF_FARPTR_2_FLAT 14h, 2*4 ; pUnLockRange653 VBOXSF_PSFFSD_2_FLAT 18h, 1*4 ; psffsd654 VBOXSF_FARPTR_2_FLAT 1ch, 0*4 ; psffsi655 call NAME(FS32_FILELOCKS)952 mov ecx, [ebp + 08h] ; flags 953 mov [esp + 5*4], ecx 954 mov edx, [ebp + 0ch] ; timeout 955 mov [esp + 4*4], edx 956 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pLockRange 957 VBOXSF_FARPTR_2_FLAT 14h, 2*4 ; pUnLockRange 958 VBOXSF_PSFFSD_2_FLAT 18h, 1*4 ; psffsd 959 VBOXSF_FARPTR_2_FLAT 1ch, 0*4 ; psffsi 960 call NAME(FS32_FILELOCKS) 656 961 VBOXSF_TO_16 FS_FILELOCKS 657 retf 18h962 retf 18h 658 963 VBOXSF_EP16_END FS_FILELOCKS 659 964 … … 664 969 VBOXSF_EP16_BEGIN FS_FILELOCKSL, 'FS_FILELOCKSL' 665 970 VBOXSF_TO_32 FS_FILELOCKSL, 6*4 666 mov ecx, [ebp + 08h] ; flags667 mov [esp + 5*4], ecx668 mov edx, [ebp + 0ch] ; timeout669 mov [esp + 4*4], edx670 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pLockRange671 VBOXSF_FARPTR_2_FLAT 14h, 2*4 ; pUnLockRange672 VBOXSF_PSFFSD_2_FLAT 18h, 1*4 ; psffsd673 VBOXSF_FARPTR_2_FLAT 1ch, 0*4 ; psffsi674 call NAME(FS32_FILELOCKS)971 mov ecx, [ebp + 08h] ; flags 972 mov [esp + 5*4], ecx 973 mov edx, [ebp + 0ch] ; timeout 974 mov [esp + 4*4], edx 975 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pLockRange 976 VBOXSF_FARPTR_2_FLAT 14h, 2*4 ; pUnLockRange 977 VBOXSF_PSFFSD_2_FLAT 18h, 1*4 ; psffsd 978 VBOXSF_FARPTR_2_FLAT 1ch, 0*4 ; psffsi 979 call NAME(FS32_FILELOCKS) 675 980 VBOXSF_TO_16 FS_FILELOCKSL 676 retf 18h981 retf 18h 677 982 VBOXSF_EP16_END FS_FILELOCKSL 678 983 … … 683 988 VBOXSF_EP16_BEGIN FS_FINDCLOSE, 'FS_FINDCLOSE' 684 989 VBOXSF_TO_32 FS_FINDCLOSE, 2*4 685 VBOXSF_PFSFSD_2_FLAT 08h, 1*4 ; pfsfsd686 VBOXSF_FARPTR_2_FLAT 0ch, 0*4 ; pfsfsi687 call NAME(FS32_FINDCLOSE)990 VBOXSF_PFSFSD_2_FLAT 08h, 1*4 ; pfsfsd 991 VBOXSF_FARPTR_2_FLAT 0ch, 0*4 ; pfsfsi 992 call NAME(FS32_FINDCLOSE) 688 993 VBOXSF_TO_16 FS_FINDCLOSE 689 retf 8h994 retf 8h 690 995 VBOXSF_EP16_END FS_FINDCLOSE 691 996 … … 698 1003 VBOXSF_EP16_BEGIN FS_FINDFIRST, 'FS_FINDFIRST' 699 1004 VBOXSF_TO_32 FS_FINDFIRST, 12*4 700 movzx ecx, word [ebp + 08h] ; flags701 mov [esp + 11*4], ecx702 movzx edx, word [ebp + 0ah] ; level703 mov [esp + 10*4], edx704 VBOXSF_FARPTR_2_FLAT 0ch, 9*4 ; pcMatch705 movzx eax, word [ebp + 10h] ; cbData706 mov [esp + 8*4], eax707 VBOXSF_FARPTR_2_FLAT 12h, 7*4 ; pbData708 VBOXSF_FARPTR_2_FLAT 16h, 6*4 ; pfsfsd709 VBOXSF_FARPTR_2_FLAT 1ah, 5*4 ; pfsfsi710 movzx ecx, word [ebp + 1eh] ; attr711 mov [esp + 4*4], ecx712 movzx edx, word [ebp + 20h] ; iCurDirEnd713 mov [esp + 3*4], edx714 VBOXSF_FARPTR_2_FLAT 22h, 2*4 ; pszName715 VBOXSF_PCDFSD_2_FLAT 26h, 1*4 ; pcdfsd716 VBOXSF_FARPTR_2_FLAT 2ah, 0*4 ; pcdfsi717 call NAME(FS32_FINDFIRST)1005 movzx ecx, word [ebp + 08h] ; flags 1006 mov [esp + 11*4], ecx 1007 movzx edx, word [ebp + 0ah] ; level 1008 mov [esp + 10*4], edx 1009 VBOXSF_FARPTR_2_FLAT 0ch, 9*4 ; pcMatch 1010 movzx eax, word [ebp + 10h] ; cbData 1011 mov [esp + 8*4], eax 1012 VBOXSF_FARPTR_2_FLAT 12h, 7*4 ; pbData 1013 VBOXSF_FARPTR_2_FLAT 16h, 6*4 ; pfsfsd 1014 VBOXSF_FARPTR_2_FLAT 1ah, 5*4 ; pfsfsi 1015 movzx ecx, word [ebp + 1eh] ; attr 1016 mov [esp + 4*4], ecx 1017 movsx edx, word [ebp + 20h] ; iCurDirEnd 1018 mov [esp + 3*4], edx 1019 VBOXSF_FARPTR_2_FLAT 22h, 2*4 ; pszName 1020 VBOXSF_PCDFSD_2_FLAT 26h, 1*4 ; pcdfsd 1021 VBOXSF_FARPTR_2_FLAT 2ah, 0*4 ; pcdfsi 1022 call NAME(FS32_FINDFIRST) 718 1023 VBOXSF_TO_16 FS_FINDFIRST 719 retf 26h1024 retf 26h 720 1025 VBOXSF_EP16_END FS_FINDFIRST 721 1026 … … 727 1032 VBOXSF_EP16_BEGIN FS_FINDFROMNAME, 'FS_FINDFROMNAME' 728 1033 VBOXSF_TO_32 FS_FINDFROMNAME, 9*4 729 movzx ecx, word [ebp + 08h] ; flags730 mov [esp + 8*4], ecx731 VBOXSF_FARPTR_2_FLAT 0ah, 7*4 ; pszName732 mov edx, [ebp + 0eh] ; position733 mov [esp + 6*4], edx734 movzx eax, word [ebp + 12h] ; level735 mov [esp + 5*4], eax736 VBOXSF_FARPTR_2_FLAT 14h, 4*4 ; pcMatch737 movzx eax, word [ebp + 18h] ; cbData738 mov [esp + 3*4], eax739 VBOXSF_FARPTR_2_FLAT 1ah, 2*4 ; pbData740 VBOXSF_PFSFSD_2_FLAT 1eh, 1*4 ; pfsfsd741 VBOXSF_FARPTR_2_FLAT 22h, 0*4 ; pfsfsi742 call NAME(FS32_FINDFROMNAME)1034 movzx ecx, word [ebp + 08h] ; flags 1035 mov [esp + 8*4], ecx 1036 VBOXSF_FARPTR_2_FLAT 0ah, 7*4 ; pszName 1037 mov edx, [ebp + 0eh] ; position 1038 mov [esp + 6*4], edx 1039 movzx eax, word [ebp + 12h] ; level 1040 mov [esp + 5*4], eax 1041 VBOXSF_FARPTR_2_FLAT 14h, 4*4 ; pcMatch 1042 movzx eax, word [ebp + 18h] ; cbData 1043 mov [esp + 3*4], eax 1044 VBOXSF_FARPTR_2_FLAT 1ah, 2*4 ; pbData 1045 VBOXSF_PFSFSD_2_FLAT 1eh, 1*4 ; pfsfsd 1046 VBOXSF_FARPTR_2_FLAT 22h, 0*4 ; pfsfsi 1047 call NAME(FS32_FINDFROMNAME) 743 1048 VBOXSF_TO_16 FS_FINDFROMNAME 744 retf 1eh1049 retf 1eh 745 1050 VBOXSF_EP16_END FS_FINDFROMNAME 746 1051 … … 752 1057 VBOXSF_EP16_BEGIN FS_FINDNEXT, 'FS_FINDNEXT' 753 1058 VBOXSF_TO_32 FS_FINDNEXT, 7*4 754 movzx ecx, word [ebp + 08h] ; flags755 mov [esp + 6*4], ecx756 movzx eax, word [ebp + 0ah] ; level757 mov [esp + 5*4], eax758 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pcMatch759 movzx eax, word [ebp + 10h] ; cbData760 mov [esp + 3*4], eax761 VBOXSF_FARPTR_2_FLAT 12h, 2*4 ; pbData762 VBOXSF_PFSFSD_2_FLAT 16h, 1*4 ; pfsfsd763 VBOXSF_FARPTR_2_FLAT 1ah, 0*4 ; pfsfsi764 call NAME(FS32_FINDNEXT)1059 movzx ecx, word [ebp + 08h] ; flags 1060 mov [esp + 6*4], ecx 1061 movzx eax, word [ebp + 0ah] ; level 1062 mov [esp + 5*4], eax 1063 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pcMatch 1064 movzx eax, word [ebp + 10h] ; cbData 1065 mov [esp + 3*4], eax 1066 VBOXSF_FARPTR_2_FLAT 12h, 2*4 ; pbData 1067 VBOXSF_PFSFSD_2_FLAT 16h, 1*4 ; pfsfsd 1068 VBOXSF_FARPTR_2_FLAT 1ah, 0*4 ; pfsfsi 1069 call NAME(FS32_FINDNEXT) 765 1070 VBOXSF_TO_16 FS_FINDNEXT 766 retf 16h1071 retf 16h 767 1072 VBOXSF_EP16_END FS_FINDNEXT 768 1073 … … 773 1078 VBOXSF_EP16_BEGIN FS_FINDNOTIFYCLOSE, 'FS_FINDNOTIFYCLOSE' 774 1079 VBOXSF_TO_32 FS_FINDNOTIFYCLOSE, 1*4 775 movzx ecx, word [ebp + 08h] ; handle776 mov [esp], ecx777 call NAME(FS32_FINDNOTIFYCLOSE)1080 movzx ecx, word [ebp + 08h] ; handle 1081 mov [esp], ecx 1082 call NAME(FS32_FINDNOTIFYCLOSE) 778 1083 VBOXSF_TO_16 FS_FINDNOTIFYCLOSE 779 retf 2h1084 retf 2h 780 1085 VBOXSF_EP16_END FS_FINDNOTIFYCLOSE 781 1086 … … 788 1093 VBOXSF_EP16_BEGIN FS_FINDNOTIFYFIRST, 'FS_FINDNOTIFYFIRST' 789 1094 VBOXSF_TO_32 FS_FINDNOTIFYFIRST, 11*4 790 movzx ecx, word [ebp + 08h] ; flags791 mov [esp + 10*4], ecx792 movzx edx, word [ebp + 0ah] ; level793 mov [esp + 9*4], edx794 VBOXSF_FARPTR_2_FLAT 0ch, 8*4 ; pcMatch795 movzx eax, word [ebp + 10h] ; cbData796 mov [esp + 7*4], eax797 VBOXSF_FARPTR_2_FLAT 12h, 6*4 ; pbData798 VBOXSF_FARPTR_2_FLAT 16h, 5*4 ; pHandle799 movzx ecx, word [ebp + 1ah] ; attr800 mov [esp + 4*4], ecx801 movzx edx, word [ebp + 1ch] ; iCurDirEnd802 mov [esp + 3*4], edx803 VBOXSF_FARPTR_2_FLAT 1eh, 2*4 ; pszName804 VBOXSF_PCDFSD_2_FLAT 22h, 1*4 ; pcdfsd805 VBOXSF_FARPTR_2_FLAT 26h, 0*4 ; pcdfsi806 call NAME(FS32_FINDNOTIFYFIRST)1095 movzx ecx, word [ebp + 08h] ; flags 1096 mov [esp + 10*4], ecx 1097 movzx edx, word [ebp + 0ah] ; level 1098 mov [esp + 9*4], edx 1099 VBOXSF_FARPTR_2_FLAT 0ch, 8*4 ; pcMatch 1100 movzx eax, word [ebp + 10h] ; cbData 1101 mov [esp + 7*4], eax 1102 VBOXSF_FARPTR_2_FLAT 12h, 6*4 ; pbData 1103 VBOXSF_FARPTR_2_FLAT 16h, 5*4 ; pHandle 1104 movzx ecx, word [ebp + 1ah] ; attr 1105 mov [esp + 4*4], ecx 1106 movsx edx, word [ebp + 1ch] ; iCurDirEnd 1107 mov [esp + 3*4], edx 1108 VBOXSF_FARPTR_2_FLAT 1eh, 2*4 ; pszName 1109 VBOXSF_PCDFSD_2_FLAT 22h, 1*4 ; pcdfsd 1110 VBOXSF_FARPTR_2_FLAT 26h, 0*4 ; pcdfsi 1111 call NAME(FS32_FINDNOTIFYFIRST) 807 1112 VBOXSF_TO_16 FS_FINDNOTIFYFIRST 808 retf 22h1113 retf 22h 809 1114 VBOXSF_EP16_END FS_FINDNOTIFYFIRST 810 1115 … … 816 1121 VBOXSF_EP16_BEGIN FS_FINDNOTIFYNEXT, 'FS_FINDNOTIFYNEXT' 817 1122 VBOXSF_TO_32 FS_FINDNOTIFYNEXT, 6*4 818 mov ecx, [ebp + 08h] ; timeout819 mov [esp + 5*4], ecx820 movzx edx, word [ebp + 0ch] ; level821 mov [esp + 4*4], edx822 VBOXSF_FARPTR_2_FLAT 0eh, 3*4 ; pcMatch823 movzx eax, word [ebp + 12h] ; cbData824 mov [esp + 2*4], eax825 VBOXSF_FARPTR_2_FLAT 14h, 1*4 ; pbData826 movzx ecx, word [ebp + 18h] ; handle827 mov [esp], ecx828 call NAME(FS32_FINDNOTIFYNEXT)1123 mov ecx, [ebp + 08h] ; timeout 1124 mov [esp + 5*4], ecx 1125 movzx edx, word [ebp + 0ch] ; level 1126 mov [esp + 4*4], edx 1127 VBOXSF_FARPTR_2_FLAT 0eh, 3*4 ; pcMatch 1128 movzx eax, word [ebp + 12h] ; cbData 1129 mov [esp + 2*4], eax 1130 VBOXSF_FARPTR_2_FLAT 14h, 1*4 ; pbData 1131 movzx ecx, word [ebp + 18h] ; handle 1132 mov [esp], ecx 1133 call NAME(FS32_FINDNOTIFYNEXT) 829 1134 VBOXSF_TO_16 FS_FINDNOTIFYNEXT 830 retf 12h1135 retf 12h 831 1136 VBOXSF_EP16_END FS_FINDNOTIFYNEXT 832 1137 … … 835 1140 VBOXSF_EP16_BEGIN FS_FLUSHBUF, 'FS_FLUSHBUF' 836 1141 VBOXSF_TO_32 FS_FLUSHBUF, 2*4 837 movzx edx, word [ebp + 08h] ; flag838 mov [esp + 1*4], edx839 movzx eax, word [ebp + 0ch] ; hVPB840 mov [esp + 0*4], eax841 call NAME(FS32_FLUSHBUF)1142 movzx edx, word [ebp + 08h] ; flag 1143 mov [esp + 1*4], edx 1144 movzx eax, word [ebp + 0ch] ; hVPB 1145 mov [esp + 0*4], eax 1146 call NAME(FS32_FLUSHBUF) 842 1147 VBOXSF_TO_16 FS_FLUSHBUF 843 retf 4h1148 retf 4h 844 1149 VBOXSF_EP16_END FS_FLUSHBUF 845 1150 … … 849 1154 ; PVOID pData, USHORT lenData, PUSHORT plenDataIO); 850 1155 VBOXSF_EP16_BEGIN FS_FSCTL, 'FS_FSCTL' 851 ;852 ; Initialized ring-0 yet? (this is a likely first entry point)853 ;854 push ds855 mov ax, DATA16856 mov ds, ax857 test byte [NAME(g_fDoneRing0)], 1858 jnz .DoneRing0859 call NAME(VBoxSFR0Init16Bit)1156 ; 1157 ; Initialized ring-0 yet? (this is a likely first entry point) 1158 ; 1159 push ds 1160 mov ax, DATA16 1161 mov ds, ax 1162 test byte [NAME(g_fDoneRing0)], 1 1163 jnz .DoneRing0 1164 call NAME(VBoxSFR0Init16Bit) 860 1165 .DoneRing0: 861 pop ds1166 pop ds 862 1167 863 1168 VBOXSF_TO_32 FS_FSCTL, 9*4 864 VBOXSF_FARPTR_2_FLAT 08h, 8*4 ; plenDataIO865 movzx ecx, word [ebp + 0ch] ; lenData866 mov [esp + 7*4], ecx867 VBOXSF_FARPTR_2_FLAT 0eh, 6*4 ; pData868 VBOXSF_FARPTR_2_FLAT 12h, 5*4 ; plenDataIO869 movzx ecx, word [ebp + 16h] ; lenData870 mov [esp + 4*4], ecx871 VBOXSF_FARPTR_2_FLAT 18h, 3*4 ; pData872 movzx edx, word [ebp + 1ch] ; func873 mov [esp + 2*4], edx874 movzx eax, word [ebp + 1eh] ; iArgType875 mov [esp + 1*4], eax876 VBOXSF_FARPTR_2_FLAT 20h, 0*4 ; pArgdat877 call NAME(FS32_FSCTL)1169 VBOXSF_FARPTR_2_FLAT 08h, 8*4 ; plenDataIO 1170 movzx ecx, word [ebp + 0ch] ; lenData 1171 mov [esp + 7*4], ecx 1172 VBOXSF_FARPTR_2_FLAT 0eh, 6*4 ; pData 1173 VBOXSF_FARPTR_2_FLAT 12h, 5*4 ; plenDataIO 1174 movzx ecx, word [ebp + 16h] ; lenData 1175 mov [esp + 4*4], ecx 1176 VBOXSF_FARPTR_2_FLAT 18h, 3*4 ; pData 1177 movzx edx, word [ebp + 1ch] ; func 1178 mov [esp + 2*4], edx 1179 movzx eax, word [ebp + 1eh] ; iArgType 1180 mov [esp + 1*4], eax 1181 VBOXSF_FARPTR_2_FLAT 20h, 0*4 ; pArgdat 1182 call NAME(FS32_FSCTL) 878 1183 VBOXSF_TO_16 FS_FSCTL 879 retf 1ch1184 retf 1ch 880 1185 VBOXSF_EP16_END FS_FSCTL 881 1186 … … 884 1189 VBOXSF_EP16_BEGIN FS_FSINFO, 'FS_FSINFO' 885 1190 VBOXSF_TO_32 FS_FSINFO, 5*4 886 movzx ecx, word [ebp + 08h] ; level887 mov [esp + 10h], ecx888 movzx edx, word [ebp + 0ah] ; cbData889 mov [esp + 0ch], edx890 VBOXSF_FARPTR_2_FLAT 0ch, 2*4 ; pbData891 movzx edx, word [ebp + 10h] ; hVPB892 mov [esp], edx893 movzx eax, word [ebp + 12h] ; flag894 mov [esp], eax895 call NAME(FS32_FSINFO)1191 movzx ecx, word [ebp + 08h] ; level 1192 mov [esp + 10h], ecx 1193 movzx edx, word [ebp + 0ah] ; cbData 1194 mov [esp + 0ch], edx 1195 VBOXSF_FARPTR_2_FLAT 0ch, 2*4 ; pbData 1196 movzx edx, word [ebp + 10h] ; hVPB 1197 mov [esp + 4], edx 1198 movzx eax, word [ebp + 12h] ; flag 1199 mov [esp], eax 1200 call NAME(FS32_FSINFO) 896 1201 VBOXSF_TO_16 FS_FSINFO 897 retf 14h1202 retf 14h 898 1203 VBOXSF_EP16_END FS_FSINFO 899 1204 … … 905 1210 VBOXSF_EP16_BEGIN FS_IOCTL, 'FS_IOCTL' 906 1211 VBOXSF_TO_32 FS_IOCTL, 10*4 907 VBOXSF_FARPTR_2_FLAT 08h, 9*4 ; plenDataIO908 movzx ecx, word [ebp + 0ch] ; lenData909 mov [esp + 8*4], ecx910 VBOXSF_FARPTR_2_FLAT 0eh, 7*4 ; pData911 VBOXSF_FARPTR_2_FLAT 12h, 6*4 ; plenDataIO912 movzx ecx, word [ebp + 16h] ; lenData913 mov [esp + 5*4], ecx914 VBOXSF_FARPTR_2_FLAT 18h, 4*4 ; pData915 movzx edx, word [ebp + 1ch] ; cat916 mov [esp + 3*4], edx917 movzx eax, word [ebp + 1eh] ; func918 mov [esp + 2*4], eax919 VBOXSF_PSFFSD_2_FLAT 20h, 1*4 ; psffsd920 VBOXSF_FARPTR_2_FLAT 24h, 0*4 ; pData921 call NAME(FS32_IOCTL)1212 VBOXSF_FARPTR_2_FLAT 08h, 9*4 ; plenDataIO 1213 movzx ecx, word [ebp + 0ch] ; lenData 1214 mov [esp + 8*4], ecx 1215 VBOXSF_FARPTR_2_FLAT 0eh, 7*4 ; pData 1216 VBOXSF_FARPTR_2_FLAT 12h, 6*4 ; plenDataIO 1217 movzx ecx, word [ebp + 16h] ; lenData 1218 mov [esp + 5*4], ecx 1219 VBOXSF_FARPTR_2_FLAT 18h, 4*4 ; pData 1220 movzx edx, word [ebp + 1ch] ; cat 1221 mov [esp + 3*4], edx 1222 movzx eax, word [ebp + 1eh] ; func 1223 mov [esp + 2*4], eax 1224 VBOXSF_PSFFSD_2_FLAT 20h, 1*4 ; psffsd 1225 VBOXSF_FARPTR_2_FLAT 24h, 0*4 ; pData 1226 call NAME(FS32_IOCTL) 922 1227 VBOXSF_TO_16 FS_IOCTL 923 retf 20h1228 retf 20h 924 1229 VBOXSF_EP16_END FS_IOCTL 925 1230 … … 930 1235 VBOXSF_EP16_BEGIN FS_MKDIR, 'FS_MKDIR' 931 1236 VBOXSF_TO_32 FS_MKDIR, 6*4 932 movzx ecx, word [ebp + 08h] ; flag933 mov [esp + 5*4], ecx934 VBOXSF_FARPTR_2_FLAT 0ah, 4*4 ; pEABuf935 movzx edx, word [ebp + 0eh] ; iCurDirEnd936 mov [esp + 3*4], edx937 VBOXSF_FARPTR_2_FLAT 10h, 2*4 ; pszName938 VBOXSF_PCDFSD_2_FLAT 14h, 1*4 ; pcdfsd939 VBOXSF_FARPTR_2_FLAT 18h, 0*4 ; pcdfsi940 call NAME(FS32_MKDIR)1237 movzx ecx, word [ebp + 08h] ; flag 1238 mov [esp + 5*4], ecx 1239 VBOXSF_FARPTR_2_FLAT 0ah, 4*4 ; pEABuf 1240 movsx edx, word [ebp + 0eh] ; iCurDirEnd 1241 mov [esp + 3*4], edx 1242 VBOXSF_FARPTR_2_FLAT 10h, 2*4 ; pszName 1243 VBOXSF_PCDFSD_2_FLAT 14h, 1*4 ; pcdfsd 1244 VBOXSF_FARPTR_2_FLAT 18h, 0*4 ; pcdfsi 1245 call NAME(FS32_MKDIR) 941 1246 VBOXSF_TO_16 FS_MKDIR 942 retf 14h1247 retf 14h 943 1248 VBOXSF_EP16_END FS_MKDIR 944 1249 … … 947 1252 ; @cproto int FS_MOUNT(USHORT flag, PVPFSI pvpfsi, PVBOXSFVP pvpfsd, USHORT hVPB, PCSZ pszBoot) 948 1253 VBOXSF_EP16_BEGIN FS_MOUNT, 'FS_MOUNT' 949 ;950 ; Initialized ring-0 yet? (this is a likely first entry point)951 ;952 push ds953 mov ax, DATA16954 mov ds, ax955 test byte [NAME(g_fDoneRing0)], 1956 jnz .DoneRing0957 call NAME(VBoxSFR0Init16Bit)1254 ; 1255 ; Initialized ring-0 yet? (this is a likely first entry point) 1256 ; 1257 push ds 1258 mov ax, DATA16 1259 mov ds, ax 1260 test byte [NAME(g_fDoneRing0)], 1 1261 jnz .DoneRing0 1262 call NAME(VBoxSFR0Init16Bit) 958 1263 .DoneRing0: 959 pop ds1264 pop ds 960 1265 961 1266 VBOXSF_TO_32 FS_MOUNT, 5*4 962 VBOXSF_FARPTR_2_FLAT 08h, 4*4 ; pszBoot963 movzx ecx, word [ebp + 0ch] ; hVPB964 mov [esp + 3*4], ecx965 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pvpfsd966 VBOXSF_FARPTR_2_FLAT 12h, 1*4 ; pvpfsi967 movzx ecx, word [ebp + 16h] ; flag968 mov [esp], ecx969 call NAME(FS32_MOUNT)1267 VBOXSF_FARPTR_2_FLAT 08h, 4*4 ; pszBoot 1268 movzx ecx, word [ebp + 0ch] ; hVPB 1269 mov [esp + 3*4], ecx 1270 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pvpfsd 1271 VBOXSF_FARPTR_2_FLAT 12h, 1*4 ; pvpfsi 1272 movzx ecx, word [ebp + 16h] ; flag 1273 mov [esp], ecx 1274 call NAME(FS32_MOUNT) 970 1275 VBOXSF_TO_16 FS_MOUNT 971 retf 10h1276 retf 10h 972 1277 VBOXSF_EP16_END FS_MOUNT 973 1278 … … 978 1283 VBOXSF_EP16_BEGIN FS_MOVE, 'FS_MOVE' 979 1284 VBOXSF_TO_32 FS_MOVE, 7*4 980 movzx ecx, word [ebp + 08h] ; type981 mov [esp + 6*4], ecx982 movzx edx, word [ebp + 0ah] ; iDstCurDirEnd983 mov [esp + 5*4], edx984 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pszDst985 movzx eax, word [ebp + 10h] ; iSrcCurDirEnd986 mov [esp + 3*4], eax987 VBOXSF_FARPTR_2_FLAT 12h, 2*4 ; pszSrc988 VBOXSF_PCDFSD_2_FLAT 16h, 1*4 ; psffsd989 VBOXSF_FARPTR_2_FLAT 1ah, 0*4 ; psffsi990 call NAME(FS32_MOVE)1285 movzx ecx, word [ebp + 08h] ; type 1286 mov [esp + 6*4], ecx 1287 movzx edx, word [ebp + 0ah] ; iDstCurDirEnd 1288 mov [esp + 5*4], edx 1289 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pszDst 1290 movzx eax, word [ebp + 10h] ; iSrcCurDirEnd 1291 mov [esp + 3*4], eax 1292 VBOXSF_FARPTR_2_FLAT 12h, 2*4 ; pszSrc 1293 VBOXSF_PCDFSD_2_FLAT 16h, 1*4 ; psffsd 1294 VBOXSF_FARPTR_2_FLAT 1ah, 0*4 ; psffsi 1295 call NAME(FS32_MOVE) 991 1296 VBOXSF_TO_16 FS_MOVE 992 retf 16h1297 retf 16h 993 1298 VBOXSF_EP16_END FS_MOVE 994 1299 … … 998 1303 VBOXSF_EP16_BEGIN FS_NEWSIZE, 'FS_NEWSIZE' 999 1304 VBOXSF_TO_32 FS_NEWSIZE, 5*4 ; thunking to longlong edition. 1000 movzx ecx, word [ebp + 08h] ; IOflag1001 mov [esp + 4*4], ecx1002 mov eax, [ebp + 0ah] ; cbFile (ULONG -> LONGLONG)1003 mov dword [esp + 3*4], 01004 mov [esp + 2*4], eax1005 VBOXSF_PSFFSD_2_FLAT 0eh, 1*4 ; psffsd1006 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; psffsi1007 call NAME(FS32_NEWSIZEL)1305 movzx ecx, word [ebp + 08h] ; IOflag 1306 mov [esp + 4*4], ecx 1307 mov eax, [ebp + 0ah] ; cbFile (ULONG -> LONGLONG) 1308 mov dword [esp + 3*4], 0 1309 mov [esp + 2*4], eax 1310 VBOXSF_PSFFSD_2_FLAT 0eh, 1*4 ; psffsd 1311 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; psffsi 1312 call NAME(FS32_NEWSIZEL) 1008 1313 VBOXSF_TO_16 FS_NEWSIZE 1009 retf 0eh1314 retf 0eh 1010 1315 VBOXSF_EP16_END FS_NEWSIZE 1011 1316 … … 1015 1320 VBOXSF_EP16_BEGIN FS_NEWSIZEL, 'FS_NEWSIZEL' 1016 1321 VBOXSF_TO_32 FS_NEWSIZEL, 5*4 1017 movzx ecx, word [ebp + 08h] ; IOflag1018 mov [esp + 4*4], ecx1019 mov eax, [ebp + 0ah] ; cbFile1020 mov edx, [ebp + 0eh]1021 mov [esp + 3*4], edx1022 mov [esp + 2*4], eax1023 VBOXSF_PSFFSD_2_FLAT 12h, 1*4 ; psffsd1024 VBOXSF_FARPTR_2_FLAT 16h, 0*4 ; psffsi1025 call NAME(FS32_NEWSIZEL)1322 movzx ecx, word [ebp + 08h] ; IOflag 1323 mov [esp + 4*4], ecx 1324 mov eax, [ebp + 0ah] ; cbFile 1325 mov edx, [ebp + 0eh] 1326 mov [esp + 3*4], edx 1327 mov [esp + 2*4], eax 1328 VBOXSF_PSFFSD_2_FLAT 12h, 1*4 ; psffsd 1329 VBOXSF_FARPTR_2_FLAT 16h, 0*4 ; psffsi 1330 call NAME(FS32_NEWSIZEL) 1026 1331 VBOXSF_TO_16 FS_NEWSIZEL 1027 retf 12h1332 retf 12h 1028 1333 VBOXSF_EP16_END FS_NEWSIZEL 1029 1334 … … 1034 1339 VBOXSF_EP16_BEGIN FS_NMPIPE, 'FS_NMPIPE' 1035 1340 VBOXSF_TO_32 FS_NMPIPE, 6*4 1036 VBOXSF_FARPTR_2_FLAT 08h, 5*4 ; pszName1037 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pData1038 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pOpRec1039 movzx ecx, word [ebp + 14h] ; OpType1040 mov [esp + 2*4], ecx1041 VBOXSF_FARPTR_2_FLAT 16h, 1*4 ; psffsd (take care...)1042 VBOXSF_FARPTR_2_FLAT 1ah, 0*4 ; psffsi1043 call NAME(FS32_NMPIPE)1341 VBOXSF_FARPTR_2_FLAT 08h, 5*4 ; pszName 1342 VBOXSF_FARPTR_2_FLAT 0ch, 4*4 ; pData 1343 VBOXSF_FARPTR_2_FLAT 10h, 3*4 ; pOpRec 1344 movzx ecx, word [ebp + 14h] ; OpType 1345 mov [esp + 2*4], ecx 1346 VBOXSF_FARPTR_2_FLAT 16h, 1*4 ; psffsd (take care...) 1347 VBOXSF_FARPTR_2_FLAT 1ah, 0*4 ; psffsi 1348 call NAME(FS32_NMPIPE) 1044 1349 VBOXSF_TO_16 FS_NMPIPE 1045 retf 16h1350 retf 16h 1046 1351 VBOXSF_EP16_END FS_NMPIPE 1047 1352 … … 1053 1358 VBOXSF_EP16_BEGIN FS_OPENCREATE, 'FS_OPENCREATE' 1054 1359 VBOXSF_TO_32 FS_OPENCREATE, 12*4 1055 VBOXSF_FARPTR_2_FLAT 08h, 11*4 ; pfgenflag1056 VBOXSF_FARPTR_2_FLAT 0ch, 10*4 ; pcEABuf1057 movzx ecx, word [ebp + 10h] ; usAttr1058 mov [esp + 9*4], ecx1059 VBOXSF_FARPTR_2_FLAT 12h, 8*4 ; pusAction1060 movzx edx, word [ebp + 16h] ; usOpenFlag1061 mov [esp + 7*4], edx1062 mov eax, [ebp + 18h] ; ulOpenMode1063 mov [esp + 6*4], eax1064 VBOXSF_FARPTR_2_FLAT 1ch, 5*4 ; psffsd (new, no short cuts)1065 VBOXSF_FARPTR_2_FLAT 20h, 4*4 ; psffsi1066 movzx ecx, word [ebp + 24h] ; iCurDirEnd1067 mov [esp + 3*4], ecx1068 VBOXSF_FARPTR_2_FLAT 26h, 2*4 ; pszName1069 VBOXSF_PCDFSD_2_FLAT 2ah, 1*4 ; pcdfsd1070 VBOXSF_FARPTR_2_FLAT 2eh, 0*4 ; pcdfsi1071 call NAME(FS32_OPENCREATE)1360 VBOXSF_FARPTR_2_FLAT 08h, 11*4 ; pfgenflag 1361 VBOXSF_FARPTR_2_FLAT 0ch, 10*4 ; pcEABuf 1362 movzx ecx, word [ebp + 10h] ; usAttr 1363 mov [esp + 9*4], ecx 1364 VBOXSF_FARPTR_2_FLAT 12h, 8*4 ; pusAction 1365 movzx edx, word [ebp + 16h] ; usOpenFlag 1366 mov [esp + 7*4], edx 1367 mov eax, [ebp + 18h] ; ulOpenMode 1368 mov [esp + 6*4], eax 1369 VBOXSF_FARPTR_2_FLAT 1ch, 5*4 ; psffsd (new, no short cuts) 1370 VBOXSF_FARPTR_2_FLAT 20h, 4*4 ; psffsi 1371 movsx ecx, word [ebp + 24h] ; iCurDirEnd 1372 mov [esp + 3*4], ecx 1373 VBOXSF_FARPTR_2_FLAT 26h, 2*4 ; pszName 1374 VBOXSF_PCDFSD_2_FLAT 2ah, 1*4 ; pcdfsd 1375 VBOXSF_FARPTR_2_FLAT 2eh, 0*4 ; pcdfsi 1376 call NAME(FS32_OPENCREATE) 1072 1377 VBOXSF_TO_16 FS_OPENCREATE 1073 retf 421378 retf 42 1074 1379 VBOXSF_EP16_END FS_OPENCREATE 1075 1380 … … 1080 1385 VBOXSF_EP16_BEGIN FS_OPENPAGEFILE, 'FS_OPENPAGEFILE' 1081 1386 VBOXSF_TO_32 FS_OPENPAGEFILE, 9*4 1082 mov ecx, [ebp + 08h] ; Reserved1083 mov [esp + 8*4], ecx1084 movzx edx, word [ebp + 0ch] ; usAttr1085 mov [esp + 7*4], edx1086 movzx eax, word [ebp + 0eh] ; usOpenFlag1087 mov [esp + 6*4], eax1088 movzx ecx, word [ebp + 10h] ; usOpenMode1089 mov [esp + 5*4], ecx1090 VBOXSF_FARPTR_2_FLAT 12h, 4*4 ; psffsd (new, no short cuts)1091 VBOXSF_FARPTR_2_FLAT 16h, 3*4 ; psffsi1092 VBOXSF_FARPTR_2_FLAT 1ah, 2*4 ; pszName1093 VBOXSF_FARPTR_2_FLAT 1eh, 1*4 ; pcMaxReq1094 VBOXSF_FARPTR_2_FLAT 22h, 0*4 ; pFlag1095 call NAME(FS32_OPENPAGEFILE)1387 mov ecx, [ebp + 08h] ; Reserved 1388 mov [esp + 8*4], ecx 1389 movzx edx, word [ebp + 0ch] ; usAttr 1390 mov [esp + 7*4], edx 1391 movzx eax, word [ebp + 0eh] ; usOpenFlag 1392 mov [esp + 6*4], eax 1393 movzx ecx, word [ebp + 10h] ; usOpenMode 1394 mov [esp + 5*4], ecx 1395 VBOXSF_FARPTR_2_FLAT 12h, 4*4 ; psffsd (new, no short cuts) 1396 VBOXSF_FARPTR_2_FLAT 16h, 3*4 ; psffsi 1397 VBOXSF_FARPTR_2_FLAT 1ah, 2*4 ; pszName 1398 VBOXSF_FARPTR_2_FLAT 1eh, 1*4 ; pcMaxReq 1399 VBOXSF_FARPTR_2_FLAT 22h, 0*4 ; pFlag 1400 call NAME(FS32_OPENPAGEFILE) 1096 1401 VBOXSF_TO_16 FS_OPENPAGEFILE 1097 retf 1eh1402 retf 1eh 1098 1403 VBOXSF_EP16_END FS_OPENPAGEFILE 1099 1404 … … 1104 1409 VBOXSF_EP16_BEGIN FS_PATHINFO, 'FS_PATHINFO' 1105 1410 VBOXSF_TO_32 FS_PATHINFO, 8*4 1106 movzx ecx, word [ebp + 08h] ; cbData1107 mov [esp + 7*4], ecx1108 VBOXSF_FARPTR_2_FLAT 0ah, 6*4 ; pData1109 movzx edx, word [ebp + 0eh] ; level1110 mov [esp + 5*4], edx1111 movzx eax, word [ebp + 10h] ; iCurDirEnd1112 mov [esp + 4*4], eax1113 VBOXSF_FARPTR_2_FLAT 12h, 3*4 ; pszName1114 VBOXSF_PCDFSD_2_FLAT 16h, 2*4 ; pcdfsd1115 VBOXSF_FARPTR_2_FLAT 1ah, 1*4 ; pcdfsi1116 movzx edx, word [ebp + 1eh] ; flag1117 mov [esp], edx1118 call NAME(FS32_PATHINFO)1411 movzx ecx, word [ebp + 08h] ; cbData 1412 mov [esp + 7*4], ecx 1413 VBOXSF_FARPTR_2_FLAT 0ah, 6*4 ; pData 1414 movzx edx, word [ebp + 0eh] ; level 1415 mov [esp + 5*4], edx 1416 movsx eax, word [ebp + 10h] ; iCurDirEnd 1417 mov [esp + 4*4], eax 1418 VBOXSF_FARPTR_2_FLAT 12h, 3*4 ; pszName 1419 VBOXSF_PCDFSD_2_FLAT 16h, 2*4 ; pcdfsd 1420 VBOXSF_FARPTR_2_FLAT 1ah, 1*4 ; pcdfsi 1421 movzx edx, word [ebp + 1eh] ; flag 1422 mov [esp], edx 1423 call NAME(FS32_PATHINFO) 1119 1424 VBOXSF_TO_16 FS_PATHINFO 1120 retf 18h1425 retf 18h 1121 1426 VBOXSF_EP16_END FS_PATHINFO 1122 1427 … … 1125 1430 VBOXSF_EP16_BEGIN FS_PROCESSNAME, 'FS_PROCESSNAME' 1126 1431 VBOXSF_TO_32 FS_PROCESSNAME, 1*4 1127 VBOXSF_FARPTR_2_FLAT 08h, 0*4 ; pszName1128 call NAME(FS32_PROCESSNAME)1432 VBOXSF_FARPTR_2_FLAT 08h, 0*4 ; pszName 1433 call NAME(FS32_PROCESSNAME) 1129 1434 VBOXSF_TO_16 FS_PROCESSNAME 1130 retf 4h1435 retf 4h 1131 1436 VBOXSF_EP16_END FS_PROCESSNAME 1132 1437 … … 1136 1441 VBOXSF_EP16_BEGIN FS_READ, 'FS_READ' 1137 1442 VBOXSF_TO_32 FS_READ, 6*4 ; extra local for ULONG cbDataTmp. 1138 movzx ecx, word [ebp + 08h] ; IOflag1139 mov [esp + 4*4], ecx1140 les dx, [ebp + 0ah] ; cbDataTmp = *pcbData;1141 movzx edx, dx1142 lea ecx, [esp + 5*4] ; pcbData = &cbDataTmp1143 movzx eax, word [es:edx]1144 mov [ecx], eax1145 mov [esp + 3*4], ecx1146 mov edx, DATA321147 mov es, edx1148 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pbData1149 VBOXSF_PSFFSD_2_FLAT 12h, 1*4 ; psffsd1150 VBOXSF_FARPTR_2_FLAT 16h, 0*4 ; psffsi1151 call FS32_READ1152 1153 les dx, [ebp + 0ah] ; *pcbData = cbDataTmp;1154 movzx edx, dx1155 mov cx, [esp + 5*4]1156 mov [es:edx], cx1157 mov edx, DATA321158 mov es, edx1443 movzx ecx, word [ebp + 08h] ; IOflag 1444 mov [esp + 4*4], ecx 1445 les dx, [ebp + 0ah] ; cbDataTmp = *pcbData; 1446 movzx edx, dx 1447 lea ecx, [esp + 5*4] ; pcbData = &cbDataTmp 1448 movzx eax, word [es:edx] 1449 mov [ecx], eax 1450 mov [esp + 3*4], ecx 1451 mov edx, DATA32 1452 mov es, edx 1453 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pbData 1454 VBOXSF_PSFFSD_2_FLAT 12h, 1*4 ; psffsd 1455 VBOXSF_FARPTR_2_FLAT 16h, 0*4 ; psffsi 1456 call FS32_READ 1457 1458 les dx, [ebp + 0ah] ; *pcbData = cbDataTmp; 1459 movzx edx, dx 1460 mov cx, [esp + 5*4] 1461 mov [es:edx], cx 1462 mov edx, DATA32 1463 mov es, edx 1159 1464 1160 1465 VBOXSF_TO_16 FS_READ 1161 1162 pop es 1163 retf 12h 1466 retf 12h 1164 1467 VBOXSF_EP16_END FS_READ 1165 1468 … … 1170 1473 VBOXSF_EP16_BEGIN FS_RMDIR, 'FS_RMDIR' 1171 1474 VBOXSF_TO_32 FS_RMDIR, 4*4 1172 movzx edx, word [ebp + 08h] ; iCurDirEnd1173 mov [esp + 3*4], edx1174 VBOXSF_FARPTR_2_FLAT 0ah, 2*4 ; pszName1175 VBOXSF_PCDFSD_2_FLAT 0eh, 1*4 ; pcdfsd1176 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; pcdfsi1177 call NAME(FS32_RMDIR)1475 movsx edx, word [ebp + 08h] ; iCurDirEnd 1476 mov [esp + 3*4], edx 1477 VBOXSF_FARPTR_2_FLAT 0ah, 2*4 ; pszName 1478 VBOXSF_PCDFSD_2_FLAT 0eh, 1*4 ; pcdfsd 1479 VBOXSF_FARPTR_2_FLAT 12h, 0*4 ; pcdfsi 1480 call NAME(FS32_RMDIR) 1178 1481 VBOXSF_TO_16 FS_RMDIR 1179 retf 14h1482 retf 0eh 1180 1483 VBOXSF_EP16_END FS_RMDIR 1181 1484 … … 1186 1489 VBOXSF_EP16_BEGIN FS_SETSWAP, 'FS_SETSWAP' 1187 1490 VBOXSF_TO_32 FS_SETSWAP, 2*4 1188 VBOXSF_PSFFSD_2_FLAT 08h, 1*4 ; psffsd1189 VBOXSF_FARPTR_2_FLAT 0ch, 0*4 ; psffsi1190 call NAME(FS32_SETSWAP)1491 VBOXSF_PSFFSD_2_FLAT 08h, 1*4 ; psffsd 1492 VBOXSF_FARPTR_2_FLAT 0ch, 0*4 ; psffsi 1493 call NAME(FS32_SETSWAP) 1191 1494 VBOXSF_TO_16 FS_SETSWAP 1192 retf 8h1495 retf 8h 1193 1496 VBOXSF_EP16_END FS_SETSWAP 1194 1497 … … 1199 1502 VBOXSF_EP16_BEGIN FS_SHUTDOWN, 'FS_SHUTDOWN' 1200 1503 VBOXSF_TO_32 FS_SHUTDOWN, 3*4 1201 mov ecx, [ebp + 08h] ; type1202 mov [esp + 1*4], edx1203 movzx edx, word [ebp + 0ah] ; reserved1204 mov [esp], eax1205 call NAME(FS32_SHUTDOWN)1504 mov ecx, [ebp + 0ch] ; type 1505 mov [esp + 1*4], edx 1506 movzx edx, word [ebp + 08h] ; reserved 1507 mov [esp], eax 1508 call NAME(FS32_SHUTDOWN) 1206 1509 VBOXSF_TO_16 FS_SHUTDOWN 1207 retf 6h1510 retf 6h 1208 1511 VBOXSF_EP16_END FS_SHUTDOWN 1512 1513 1514 ;; 1515 ; @cproto int FS_VERIFYUNCNAME(USHORT type, PCSZ pszName); 1516 ; 1517 VBOXSF_EP16_BEGIN FS_VERIFYUNCNAME, 'FS_VERIFYUNCNAME' 1518 VBOXSF_TO_32 FS_VERIFYUNCNAME, 3*4 1519 VBOXSF_FARPTR_2_FLAT 08h, 1*4 ; pszDev 1520 movzx ecx, word [ebp + 0ch] ; fFlag 1521 mov [esp], ecx 1522 call NAME(FS32_VERIFYUNCNAME) 1523 VBOXSF_TO_16 FS_VERIFYUNCNAME 1524 retf 6h 1525 VBOXSF_EP16_END FS_VERIFYUNCNAME 1209 1526 1210 1527 … … 1213 1530 VBOXSF_EP16_BEGIN FS_WRITE, 'FS_WRITE' 1214 1531 VBOXSF_TO_32 FS_WRITE, 6*4 ; extra local for ULONG cbDataTmp. 1215 movzx ecx, word [ebp + 08h] ; IOflag1216 mov [esp + 4*4], ecx1217 les dx, [ebp + 0ah] ; cbDataTmp = *pcbData;1218 movzx edx, dx1219 lea ecx, [esp + 5*4] ; pcbData = &cbDataTmp1220 movzx eax, word [es:edx]1221 mov [ecx], eax1222 mov [esp + 3*4], ecx1223 mov edx, DATA321224 mov es, edx1225 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pbData1226 VBOXSF_PSFFSD_2_FLAT 12h, 1*4 ; psffsd1227 VBOXSF_FARPTR_2_FLAT 16h, 0*4 ; psffsi1228 call FS32_WRITE1229 1230 les dx, [ebp + 0ah] ; *pcbData = cbDataTmp;1231 movzx edx, dx1232 mov cx, [esp + 5*4]1233 mov [es:edx], cx1234 mov edx, DATA321235 mov es, edx1532 movzx ecx, word [ebp + 08h] ; IOflag 1533 mov [esp + 4*4], ecx 1534 les dx, [ebp + 0ah] ; cbDataTmp = *pcbData; 1535 movzx edx, dx 1536 lea ecx, [esp + 5*4] ; pcbData = &cbDataTmp 1537 movzx eax, word [es:edx] 1538 mov [ecx], eax 1539 mov [esp + 3*4], ecx 1540 mov edx, DATA32 1541 mov es, edx 1542 VBOXSF_FARPTR_2_FLAT 0eh, 2*4 ; pbData 1543 VBOXSF_PSFFSD_2_FLAT 12h, 1*4 ; psffsd 1544 VBOXSF_FARPTR_2_FLAT 16h, 0*4 ; psffsi 1545 call FS32_WRITE 1546 1547 les dx, [ebp + 0ah] ; *pcbData = cbDataTmp; 1548 movzx edx, dx 1549 mov cx, [esp + 5*4] 1550 mov [es:edx], cx 1551 mov edx, DATA32 1552 mov es, edx 1236 1553 1237 1554 VBOXSF_TO_16 FS_WRITE 1238 1239 pop es 1240 retf 12h 1555 retf 12h 1241 1556 VBOXSF_EP16_END FS_WRITE 1242 1557 1558 1559 ; 1560 ; 1561 ; Calling 16-bit kernel code. 1562 ; 1563 ; 1564 1565 BEGINCODE 1566 1567 ;; 1568 ; Wrapper around FSH_GETVOLPARM. 1569 ; 1570 ; @returns VPBFSD. 1571 ; @param hVbp The volume handle to resolve. 1572 ; @param ppVbpFsi 1573 ; 1574 BEGINPROC Fsh32GetVolParams 1575 VBOXSF_FROM_32 Fsh32GetVolParams, 2*4 1576 mov di, sp ; make the top of the stack addressable via di 1577 1578 mov [ss:di], eax ; clear the return variables 1579 mov [ss:di + 4], eax 1580 1581 mov ax, [bp + 8] ; hVbp 1582 push ax 1583 1584 lea ax, [ss:di] ; &hvfsi 1585 push ss 1586 push ax 1587 1588 lea ax, [ss:di + 4] ; &hvfsd 1589 push ss 1590 push ax 1591 1592 call far FSH_GETVOLPARM 1593 1594 mov sp, di ; paranoia (pascal pops params) 1595 1596 VBOXSF_FROM_16_SWITCH Fsh32GetVolParams 1597 1598 ; Convert vpfsi to flat and store it in return location. 1599 mov ebx, [ebp + 0ch] 1600 test ebx, ebx 1601 jz .no_vpfsi 1602 call KernSelToFlat 1603 mov [ebx], eax 1604 .no_vpfsi: 1605 add esp, 4 1606 1607 ; Convert vpfsd to flat and return it. 1608 call KernSelToFlat 1609 1610 VBOXSF_FROM_16_EPILOGUE 1611 ret 1612 ENDPROC Fsh32GetVolParams 1243 1613 1244 1614 … … 1264 1634 VBOXSF_EP16_BEGIN FS_INIT, 'FS_INIT' 1265 1635 ; DEBUG_STR16 'VBoxSF: FS_INIT - enter' 1266 push ebp1267 mov ebp, esp1268 push ds ; bp - 02h1269 push es ; bp - 04h1270 push esi ; bp - 08h1271 push edi ; bp - 0ch1272 1273 mov ax, DATA161274 mov ds, ax1275 mov es, ax1276 1277 ;1278 ; Save the device help entry point.1279 ;1280 mov eax, [bp + 0ch]1281 mov [NAME(g_fpfnDevHlp)], eax1282 1283 ;1284 ; Parse the command line.1285 ; Doing this in assembly is kind of ugly...1286 ;1287 cmp word [bp + 10h + 2], 31288 jbe near .no_command_line1289 lds si, [bp + 10h] ; ds:si -> command line iterator.1636 push ebp 1637 mov ebp, esp 1638 push ds ; bp - 02h 1639 push es ; bp - 04h 1640 push esi ; bp - 08h 1641 push edi ; bp - 0ch 1642 1643 mov ax, DATA16 1644 mov ds, ax 1645 mov es, ax 1646 1647 ; 1648 ; Save the device help entry point. 1649 ; 1650 mov eax, [bp + 0ch] 1651 mov [NAME(g_fpfnDevHlp)], eax 1652 1653 ; 1654 ; Parse the command line. 1655 ; Doing this in assembly is kind of ugly... 1656 ; 1657 cmp word [bp + 10h + 2], 3 1658 jbe near .no_command_line 1659 lds si, [bp + 10h] ; ds:si -> command line iterator. 1290 1660 .parse_next: 1291 1661 1292 ; skip leading blanks.1662 ; skip leading blanks. 1293 1663 .parse_next_char: 1294 mov di, si ; DI = start of argument.1295 lodsb1296 cmp al, ' '1297 je .parse_next_char1298 cmp al, 9 ; tab1299 je .parse_next_char1300 cmp al, 01301 je near .parse_done1302 1303 ; check for '/' or '-'1304 cmp al, '/'1305 je .parse_switch1306 cmp al, '-'1307 je .parse_switch1308 jmp .parse_error1309 1310 ; parse switches.1664 mov di, si ; DI = start of argument. 1665 lodsb 1666 cmp al, ' ' 1667 je .parse_next_char 1668 cmp al, 9 ; tab 1669 je .parse_next_char 1670 cmp al, 0 1671 je near .parse_done 1672 1673 ; check for '/' or '-' 1674 cmp al, '/' 1675 je .parse_switch 1676 cmp al, '-' 1677 je .parse_switch 1678 jmp .parse_error 1679 1680 ; parse switches. 1311 1681 .parse_switch: 1312 lodsb1313 cmp al, 01314 je .parse_error1315 and al, ~20h ; uppercase1316 1317 cmp al, 'V' ; /V - verbose1318 je .parse_verbose1319 cmp al, 'Q' ; /Q - quiet.1320 je .parse_quiet1321 jmp .parse_error1682 lodsb 1683 cmp al, 0 1684 je .parse_error 1685 and al, ~20h ; uppercase 1686 1687 cmp al, 'V' ; /V - verbose 1688 je .parse_verbose 1689 cmp al, 'Q' ; /Q - quiet. 1690 je .parse_quiet 1691 jmp .parse_error 1322 1692 1323 1693 .parse_verbose: 1324 mov byte [es:NAME(g_fVerbose)], 11325 jmp .parse_next1694 mov byte [es:NAME(g_fVerbose)], 1 1695 jmp .parse_next 1326 1696 1327 1697 .parse_quiet: 1328 mov byte [es:NAME(g_fVerbose)], 01329 jmp .parse_next1698 mov byte [es:NAME(g_fVerbose)], 0 1699 jmp .parse_next 1330 1700 1331 1701 .parse_error: 1332 1702 segment DATA16 1333 1703 .szSyntaxError: 1334 db 0dh, 0ah, 'VBoxSF.ifs: command line parse error at: ', 01704 db 0dh, 0ah, 'VBoxSF.ifs: command line parse error at: ', 0 1335 1705 .szNewLine: 1336 db 0dh, 0ah, 0dh, 0ah, 01706 db 0dh, 0ah, 0dh, 0ah, 0 1337 1707 segment CODE16 1338 mov bx, .szSyntaxError1339 call NAME(FS_INIT_FPUTS)1340 1341 push es1342 push ds1343 pop es1344 mov bx, di1345 call NAME(FS_INIT_FPUTS)1346 pop es1347 1348 mov bx, .szNewLine1349 call NAME(FS_INIT_FPUTS)1350 1351 mov ax, ERROR_INVALID_PARAMETER1352 jmp .done1708 mov bx, .szSyntaxError 1709 call NAME(FS_INIT_FPUTS) 1710 1711 push es 1712 push ds 1713 pop es 1714 mov bx, di 1715 call NAME(FS_INIT_FPUTS) 1716 pop es 1717 1718 mov bx, .szNewLine 1719 call NAME(FS_INIT_FPUTS) 1720 1721 mov ax, ERROR_INVALID_PARAMETER 1722 jmp .done 1353 1723 1354 1724 .parse_done: 1355 mov ax, DATA161356 mov ds, ax1725 mov ax, DATA16 1726 mov ds, ax 1357 1727 .no_command_line: 1358 1728 1359 ;1360 ; Write our greeting to STDOUT.1361 ; APIRET _Pascal DosWrite(HFILE hf, PVOID pvBuf, USHORT cbBuf, PUSHORT pcbBytesWritten);1362 ;1363 cmp byte [NAME(g_fVerbose)], 01364 je near .quiet1729 ; 1730 ; Write our greeting to STDOUT. 1731 ; APIRET _Pascal DosWrite(HFILE hf, PVOID pvBuf, USHORT cbBuf, PUSHORT pcbBytesWritten); 1732 ; 1733 cmp byte [NAME(g_fVerbose)], 0 1734 je near .quiet 1365 1735 segment DATA16 1366 1736 .szMessage: 1367 db 'VirtualBox Guest Additions IFS for OS/2', 0dh, 0ah, 01737 db 'VirtualBox Guest Additions IFS for OS/2', 0dh, 0ah, 0 1368 1738 segment CODE16 1369 mov bx, .szMessage1370 call NAME(FS_INIT_FPUTS)1739 mov bx, .szMessage 1740 call NAME(FS_INIT_FPUTS) 1371 1741 .quiet: 1372 1742 1373 ; return success.1374 xor eax, eax1743 ; return success. 1744 xor eax, eax 1375 1745 .done: 1376 lea sp, [bp - 0ch]1377 pop edi1378 pop esi1379 pop es1380 pop ds1381 mov esp, ebp1382 pop ebp1383 DEBUG_STR16 'VBoxSF: FS_INIT - leave'1384 retf 0ch1746 lea sp, [bp - 0ch] 1747 pop edi 1748 pop esi 1749 pop es 1750 pop ds 1751 mov esp, ebp 1752 pop ebp 1753 DEBUG_STR16 'VBoxSF: FS_INIT - leave' 1754 retf 0ch 1385 1755 VBOXSF_EP16_END FS_INIT 1386 1756 … … 1392 1762 ; @uses nothing. 1393 1763 GLOBALNAME FS_INIT_FPUTS 1394 push bp1395 mov bp, sp1396 push es ; bp - 02h1397 push ds ; bp - 04h1398 push ax ; bp - 06h1399 push bx ; bp - 08h1400 push cx ; bp - 0ah1401 push dx ; bp - 0ch1402 push si ; bp - 0eh1403 push di ; bp - 10h1404 1405 ; cx = strlen(es:bx)1406 xor al, al1407 mov di, bx1408 mov cx, 0ffffh1409 cld1410 repne scasb1411 not cx1412 dec cx1413 1414 ; APIRET _Pascal DosWrite(HFILE hf, PVOID pvBuf, USHORT cbBuf, PUSHORT pcbBytesWritten);1415 push cx1416 mov ax, sp ; cbBytesWritten1417 push 1 ; STDOUT1418 push es ; pvBuf1419 push bx1420 push cx ; cbBuf1421 push ss ; pcbBytesWritten1422 push ax1764 push bp 1765 mov bp, sp 1766 push es ; bp - 02h 1767 push ds ; bp - 04h 1768 push ax ; bp - 06h 1769 push bx ; bp - 08h 1770 push cx ; bp - 0ah 1771 push dx ; bp - 0ch 1772 push si ; bp - 0eh 1773 push di ; bp - 10h 1774 1775 ; cx = strlen(es:bx) 1776 xor al, al 1777 mov di, bx 1778 mov cx, 0ffffh 1779 cld 1780 repne scasb 1781 not cx 1782 dec cx 1783 1784 ; APIRET _Pascal DosWrite(HFILE hf, PVOID pvBuf, USHORT cbBuf, PUSHORT pcbBytesWritten); 1785 push cx 1786 mov ax, sp ; cbBytesWritten 1787 push 1 ; STDOUT 1788 push es ; pvBuf 1789 push bx 1790 push cx ; cbBuf 1791 push ss ; pcbBytesWritten 1792 push ax 1423 1793 %if 0 ; wlink/nasm generates a non-aliased fixup here which results in 16-bit offset with the flat 32-bit selector. 1424 call far DOS16WRITE1794 call far DOS16WRITE 1425 1795 %else 1426 ; convert flat pointer to a far pointer using the tiled algorithm.1427 mov ax, DATA32 wrt FLAT1428 mov ds, ax1429 mov eax, g_pfnDos16Write wrt FLAT1430 movzx eax, word [eax + 2] ; High word of the flat address (in DATA32).1431 shl ax, 31432 or ax, 0007h1433 mov dx, DATA161434 mov ds, dx1435 mov [NAME(g_fpfnDos16Write) + 2], ax ; Update the selector (in DATA16).1436 ; do the call1437 call far [NAME(g_fpfnDos16Write)]1796 ; convert flat pointer to a far pointer using the tiled algorithm. 1797 mov ax, DATA32 wrt FLAT 1798 mov ds, ax 1799 mov eax, g_pfnDos16Write wrt FLAT 1800 movzx eax, word [eax + 2] ; High word of the flat address (in DATA32). 1801 shl ax, 3 1802 or ax, 0007h 1803 mov dx, DATA16 1804 mov ds, dx 1805 mov [NAME(g_fpfnDos16Write) + 2], ax ; Update the selector (in DATA16). 1806 ; do the call 1807 call far [NAME(g_fpfnDos16Write)] 1438 1808 %endif 1439 1809 1440 lea sp, [bp - 10h]1441 pop di1442 pop si1443 pop dx1444 pop cx1445 pop bx1446 pop ax1447 pop ds1448 pop es1449 pop bp1450 ret1810 lea sp, [bp - 10h] 1811 pop di 1812 pop si 1813 pop dx 1814 pop cx 1815 pop bx 1816 pop ax 1817 pop ds 1818 pop es 1819 pop bp 1820 ret 1451 1821 ENDPROC FS_INIT_FPUTS 1452 1822 … … 1459 1829 ; 1460 1830 GLOBALNAME VBoxSFR0Init16Bit 1461 DEBUG_STR16 'VBoxSF: VBoxSFR0Init16Bit - enter'1462 push ds1463 push es1464 push fs1465 push gs1466 push esi1467 push edi1468 push ebp1469 mov ebp, esp1470 and sp, 0fffch1471 1472 ;1473 ; Only try once.1474 ;1475 mov ax, DATA161476 mov ds, ax1477 mov byte [NAME(g_fDoneRing0)], 11478 1479 ;1480 ; Try attach to the VBoxGuest driver.1481 ;1482 mov bx, NAME(g_szVBoxGuestName)1483 mov di, NAME(g_VBoxGuestAttachDD)1484 mov dl, DevHlp_AttachDD1485 call far [NAME(g_fpfnDevHlp)]1486 jc .attach_attempt_done1487 1488 push seg NAME(g_VBoxGuestIDC)1489 push NAME(g_VBoxGuestIDC)1490 call far [NAME(g_VBoxGuestAttachDD) + 6]1831 DEBUG_STR16 'VBoxSF: VBoxSFR0Init16Bit - enter' 1832 push ds 1833 push es 1834 push fs 1835 push gs 1836 push esi 1837 push edi 1838 push ebp 1839 mov ebp, esp 1840 and sp, 0fffch 1841 1842 ; 1843 ; Only try once. 1844 ; 1845 mov ax, DATA16 1846 mov ds, ax 1847 mov byte [NAME(g_fDoneRing0)], 1 1848 1849 ; 1850 ; Try attach to the VBoxGuest driver. 1851 ; 1852 mov bx, NAME(g_szVBoxGuestName) 1853 mov di, NAME(g_VBoxGuestAttachDD) 1854 mov dl, DevHlp_AttachDD 1855 call far [NAME(g_fpfnDevHlp)] 1856 jc .attach_attempt_done 1857 1858 push seg NAME(g_VBoxGuestIDC) 1859 push NAME(g_VBoxGuestIDC) 1860 call far [NAME(g_VBoxGuestAttachDD) + 6] 1491 1861 .attach_attempt_done: 1492 1862 1493 1863 %ifndef DONT_LOCK_SEGMENTS 1494 ;1495 ; Lock the two 16-bit segments.1496 ;1497 push DATA161498 call far FSH_FORCENOSWAP1499 push CODE161500 call far FSH_FORCENOSWAP1501 ; Wonder if this'll work if wlink could mark the two segments as ALIASed...1502 ;push DATA321503 ;call far FSH_FORCENOSWAP1504 ;push TEXT321505 ;call far FSH_FORCENOSWAP1864 ; 1865 ; Lock the two 16-bit segments. 1866 ; 1867 push DATA16 1868 call far FSH_FORCENOSWAP 1869 push CODE16 1870 call far FSH_FORCENOSWAP 1871 ; Wonder if this'll work if wlink could mark the two segments as ALIASed... 1872 ;push DATA32 1873 ;call far FSH_FORCENOSWAP 1874 ;push TEXT32 1875 ;call far FSH_FORCENOSWAP 1506 1876 %endif 1507 1877 1508 ;1509 ; Do 32-bit ring-0 init.1510 ;1511 ;jmp far dword NAME(VBoxSFR0Init16Bit_32) wrt FLAT1512 db 066h1513 db 0eah1514 dd NAME(VBoxSFR0Init16Bit_32) ;wrt FLAT1515 dw TEXT32 wrt FLAT1878 ; 1879 ; Do 32-bit ring-0 init. 1880 ; 1881 ;jmp far dword NAME(VBoxSFR0Init16Bit_32) wrt FLAT 1882 db 066h 1883 db 0eah 1884 dd NAME(VBoxSFR0Init16Bit_32) ;wrt FLAT 1885 dw TEXT32 wrt FLAT 1516 1886 segment TEXT32 1517 1887 GLOBALNAME VBoxSFR0Init16Bit_32 1518 mov ax, DATA32 wrt FLAT1519 mov ds, ax1520 mov es, ax1521 1522 call KernThunkStackTo321523 call NAME(VBoxSFR0Init)1524 call KernThunkStackTo161525 1526 ;jmp far dword NAME(VBoxSFR0Init16Bit_16) wrt CODE161527 db 066h1528 db 0eah1529 dw NAME(VBoxSFR0Init16Bit_16) wrt CODE161530 dw CODE161888 mov ax, DATA32 wrt FLAT 1889 mov ds, ax 1890 mov es, ax 1891 1892 call KernThunkStackTo32 1893 call NAME(VBoxSFR0Init) 1894 call KernThunkStackTo16 1895 1896 ;jmp far dword NAME(VBoxSFR0Init16Bit_16) wrt CODE16 1897 db 066h 1898 db 0eah 1899 dw NAME(VBoxSFR0Init16Bit_16) wrt CODE16 1900 dw CODE16 1531 1901 segment CODE16 1532 1902 GLOBALNAME VBoxSFR0Init16Bit_16 1533 1903 1534 mov esp, ebp1535 pop ebp1536 pop edi1537 pop esi1538 pop gs1539 pop fs1540 pop es1541 pop ds1542 DEBUG_STR16 'VBoxSF: VBoxSFR0Init16Bit - leave'1543 ret1904 mov esp, ebp 1905 pop ebp 1906 pop edi 1907 pop esi 1908 pop gs 1909 pop fs 1910 pop es 1911 pop ds 1912 DEBUG_STR16 'VBoxSF: VBoxSFR0Init16Bit - leave' 1913 ret 1544 1914 ENDPROC VBoxSFR0Init16Bit 1545 1915 … … 1551 1921 ; 1552 1922 GLOBALNAME dbgstr16 1553 push ds1554 push ebx1555 push edx1556 1557 mov bx, ax1558 mov dx, 0504h ; RTLOG_DEBUG_PORT1559 mov ax, DATA161560 mov ds, ax1923 push ds 1924 push ebx 1925 push edx 1926 1927 mov bx, ax 1928 mov dx, 0504h ; RTLOG_DEBUG_PORT 1929 mov ax, DATA16 1930 mov ds, ax 1561 1931 1562 1932 .next: 1563 mov al, [bx]1564 or al, al1565 jz .done1566 inc bx1567 out dx, al1568 jmp .next1933 mov al, [bx] 1934 or al, al 1935 jz .done 1936 inc bx 1937 out dx, al 1938 jmp .next 1569 1939 1570 1940 .done: 1571 pop edx1572 pop ebx1573 pop ds1574 ret1941 pop edx 1942 pop ebx 1943 pop ds 1944 ret 1575 1945 ENDPROC dbgstr16 1576 1946 %endif 1577 1947 1948 1949 %ifdef WITH_DWARF 1950 ; 1951 ; Close debug info 1952 ; 1953 segment _debug_info 1954 db 0 1955 g_dwarf_compile_unit_end: 1956 %endif 1957 -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFFile.cpp
r68612 r75337 5 5 6 6 /* 7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>7 * Copyright (c) 2007-2018 knut st. osmundsen <[email protected]> 8 8 * 9 9 * Permission is hereby granted, free of charge, to any person … … 37 37 38 38 #include <VBox/log.h> 39 #include <iprt/asm.h> 39 40 #include <iprt/assert.h> 40 41 42 43 DECLASM(int) 44 FS32_OPENCREATE(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszName, USHORT iCurDirEnd, 45 PSFFSI psffsi, PVBOXSFFSD psffsd, ULONG uOpenMode, USHORT fOpenFlag, 46 PUSHORT puAction, USHORT fAttr, PBYTE pbEABuf, PUSHORT pfGenFlag) 47 { 48 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszName); NOREF(iCurDirEnd); NOREF(psffsi); NOREF(psffsd); NOREF(uOpenMode); 49 NOREF(fOpenFlag); NOREF(puAction); NOREF(fAttr); NOREF(pbEABuf); NOREF(pfGenFlag); 50 return ERROR_NOT_SUPPORTED; 51 } 52 53 54 DECLASM(int) 55 FS32_CLOSE(ULONG uType, ULONG fIoFlags, PSFFSI psffsi, PVBOXSFFSD psffsd) 56 { 57 NOREF(uType); NOREF(fIoFlags); NOREF(psffsi); NOREF(psffsd); 58 return ERROR_NOT_SUPPORTED; 59 } 60 61 62 DECLASM(int) 63 FS32_COMMIT(ULONG uType, ULONG fIoFlags, PSFFSI psffsi, PVBOXSFFSD psffsd) 64 { 65 NOREF(uType); NOREF(fIoFlags); NOREF(psffsi); NOREF(psffsd); 66 return ERROR_NOT_SUPPORTED; 41 #include <iprt/mem.h> 42 43 44 45 DECLASM(APIRET) 46 FS32_OPENCREATE(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszName, LONG offCurDirEnd, 47 PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG fOpenMode, USHORT fOpenFlags, 48 PUSHORT puAction, ULONG fAttribs, BYTE const *pbEaBuf, PUSHORT pfGenFlag) 49 { 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 pCdFsi, pCdFsd, pszName, pszName, offCurDirEnd, pSfFsi, pSfFsd, fOpenMode, fOpenFlags, puAction, fAttribs, pbEaBuf, pfGenFlag)); 52 RT_NOREF(pfGenFlag); 53 54 /* 55 * Validate and convert parameters. 56 */ 57 /* No EAs. */ 58 if (!pbEaBuf) 59 { /* likely */ } 60 else 61 { 62 LogRel(("FS32_OPENCREATE: Returns ERROR_EAS_NOT_SUPPORTED [%p];\n", pbEaBuf)); 63 return ERROR_EAS_NOT_SUPPORTED; 64 } 65 66 /* No direct access. */ 67 if (!(fOpenMode & OPEN_FLAGS_DASD)) 68 { /* likely */ } 69 else 70 { 71 LogRel(("FS32_OPENCREATE: Returns ERROR_ACCESS_DENIED [DASD];\n")); 72 return ERROR_ACCESS_DENIED; 73 } 74 75 SHFLCREATEPARMS *pParams = (SHFLCREATEPARMS *)VbglR0PhysHeapAlloc(sizeof(*pParams)); 76 if (!pParams) 77 return ERROR_NOT_ENOUGH_MEMORY; 78 RT_ZERO(*pParams); 79 80 /* access: */ 81 if (fOpenMode & OPEN_ACCESS_READWRITE) 82 pParams->CreateFlags = SHFL_CF_ACCESS_READWRITE | SHFL_CF_ACCESS_ATTR_READWRITE; 83 else if (fOpenMode & OPEN_ACCESS_WRITEONLY) 84 pParams->CreateFlags = SHFL_CF_ACCESS_WRITE | SHFL_CF_ACCESS_ATTR_WRITE; 85 else 86 pParams->CreateFlags = SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ; /* read or/and exec */ 87 88 /* Sharing: */ 89 switch (fOpenMode & (OPEN_SHARE_DENYNONE | OPEN_SHARE_DENYREADWRITE | OPEN_SHARE_DENYREAD | OPEN_SHARE_DENYWRITE)) 90 { 91 case OPEN_SHARE_DENYNONE: pParams->CreateFlags |= SHFL_CF_ACCESS_DENYNONE; break; 92 case OPEN_SHARE_DENYWRITE: pParams->CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; break; 93 case OPEN_SHARE_DENYREAD: pParams->CreateFlags |= SHFL_CF_ACCESS_DENYREAD; break; 94 case OPEN_SHARE_DENYREADWRITE: pParams->CreateFlags |= SHFL_CF_ACCESS_DENYALL; break; 95 case 0: pParams->CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; break; /* compatibility */ 96 default: 97 LogRel(("FS32_OPENCREATE: Invalid file sharing mode: %#x\n", fOpenMode)); 98 VbglR0PhysHeapFree(pParams); 99 return VERR_INVALID_PARAMETER; 100 101 } 102 103 /* How to open the file: */ 104 switch (fOpenFlags & 0x13) 105 { 106 case OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x00 */ 107 pParams->CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; 108 break; 109 case OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x10 */ 110 pParams->CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; 111 break; 112 case OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x01 */ 113 pParams->CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; 114 break; 115 case OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x11 */ 116 pParams->CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; 117 break; 118 case OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW: /* 0x02 */ 119 pParams->CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; 120 break; 121 case OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW: /* 0x12 */ 122 pParams->CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; 123 break; 124 default: 125 LogRel(("FS32_OPENCREATE: Invalid file open flags: %#x\n", fOpenFlags)); 126 VbglR0PhysHeapFree(pParams); 127 return VERR_INVALID_PARAMETER; 128 } 129 130 /* Misc: cache, etc? There seems to be no API for that. */ 131 132 /* Attributes: */ 133 pParams->Info.Attr.fMode = ((uint32_t)fAttribs << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_OS2; 134 135 /* Initial size: */ 136 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)) 155 { 156 switch (pParams->Result) 157 { 158 case SHFL_FILE_EXISTS: 159 if (pParams->Handle == SHFL_HANDLE_NIL) 160 { 161 rc = 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 } 202 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_FILE_NOT_FOUND; 211 break; 212 } 213 } 214 else if (rc == VERR_ALREADY_EXISTS) 215 rc = ERROR_ACCESS_DENIED; 216 else 217 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_PATH_NOT_FOUND); 218 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 219 } 220 VbglR0PhysHeapFree(pParams); 221 LogFlow(("FS32_OPENCREATE: returns %u\n", rc)); 222 return rc; 223 } 224 225 226 DECLASM(APIRET) 227 FS32_CLOSE(ULONG uType, ULONG fIoFlags, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd) 228 { 229 LogFlow(("FS32_CLOSE: uType=%#x fIoFlags=%#x pSfFsi=%p pSfFsd=%p:{%#x}\n", uType, fIoFlags, pSfFsi, pSfFsd, pSfFsd->u32Magic)); 230 231 /* 232 * Validate input. 233 */ 234 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 235 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 236 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 237 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 238 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 239 Assert(pFolder->cOpenFiles > 0); 240 241 /* 242 * We only care for when the system is done truly with the file 243 * and we can close it. 244 */ 245 if (uType != FS_CL_FORSYS) 246 return NO_ERROR; 247 248 /** @todo flush file if fIoFlags says so? */ 249 RT_NOREF(fIoFlags); 250 251 int vrc = VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile); 252 AssertRC(vrc); 253 254 pSfFsd->hHostFile = SHFL_HANDLE_NIL; 255 pSfFsd->pSelf = NULL; 256 pSfFsd->u32Magic = ~VBOXSFSYFI_MAGIC; 257 pSfFsd->pFolder = NULL; 258 259 ASMAtomicDecU32(&pFolder->cOpenFiles); 260 vboxSfOs2ReleaseFolder(pFolder); 261 262 RT_NOREF(pSfFsi); 263 LogFlow(("FS32_CLOSE: returns NO_ERROR\n")); 264 return NO_ERROR; 265 } 266 267 268 DECLASM(APIRET) 269 FS32_COMMIT(ULONG uType, ULONG fIoFlags, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd) 270 { 271 LogFlow(("FS32_COMMIT: uType=%#x fIoFlags=%#x pSfFsi=%p pSfFsd=%p:{%#x}\n", uType, fIoFlags, pSfFsi, pSfFsd, pSfFsd->u32Magic)); 272 273 /* 274 * Validate input. 275 */ 276 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 277 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 278 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 279 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 280 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 281 Assert(pFolder->cOpenFiles > 0); 282 RT_NOREF(pFolder); 283 284 /* 285 * We only need to flush writable files. 286 */ 287 if ( (pSfFsi->sfi_mode & SFMODE_OPEN_ACCESS) == SFMODE_OPEN_WRITEONLY 288 || (pSfFsi->sfi_mode & SFMODE_OPEN_ACCESS) == SFMODE_OPEN_READWRITE) 289 { 290 int vrc = VbglR0SfFlush(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile); 291 if (RT_FAILURE(vrc)) 292 { 293 LogRel(("FS32_COMMIT: VbglR0SfFlush failed: %Rrc\n", vrc)); 294 return ERROR_FLUSHBUF_FAILED; 295 } 296 } 297 298 NOREF(uType); NOREF(fIoFlags); NOREF(pSfFsi); 299 LogFlow(("FS32_COMMIT: returns NO_ERROR\n")); 300 return NO_ERROR; 67 301 } 68 302 69 303 70 304 extern "C" APIRET APIENTRY 71 FS32_CHGFILEPTRL(PSFFSI psffsi, PVBOXSFFSD psffsd, LONGLONG off, ULONG uMethod, ULONG fIoFlags) 72 { 73 NOREF(psffsi); NOREF(psffsd); NOREF(off); NOREF(uMethod); NOREF(fIoFlags); 74 return ERROR_NOT_SUPPORTED; 305 FS32_CHGFILEPTRL(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, LONGLONG off, ULONG uMethod, ULONG fIoFlags) 306 { 307 LogFlow(("FS32_CHGFILEPTRL: pSfFsi=%p pSfFsd=%p off=%RI64 (%#RX64) uMethod=%u fIoFlags=%#x\n", 308 pSfFsi, pSfFsd, off, off, uMethod, fIoFlags)); 309 310 /* 311 * Validate input. 312 */ 313 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 314 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 315 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 316 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 317 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 318 Assert(pFolder->cOpenFiles > 0); 319 320 /* 321 * Calc absolute offset. 322 */ 323 int64_t offNew; 324 switch (uMethod) 325 { 326 case CFP_RELBEGIN: 327 if (off >= 0) 328 { 329 offNew = off; 330 break; 331 } 332 Log(("FS32_CHGFILEPTRL: Negative seek (BEGIN): %RI64\n", off)); 333 return ERROR_NEGATIVE_SEEK; 334 335 case CFP_RELCUR: 336 offNew = pSfFsi->sfi_positionl + off; 337 if (offNew >= 0) 338 break; 339 Log(("FS32_CHGFILEPTRL: Negative seek (RELCUR): %RU64 + %RI64\n", pSfFsi->sfi_positionl, off)); 340 return ERROR_NEGATIVE_SEEK; 341 342 case CFP_RELEND: 343 { 344 /* Have to consult the host to get the current file size. */ 345 346 PSHFLFSOBJINFO pObjInfo = (PSHFLFSOBJINFO)VbglR0PhysHeapAlloc(sizeof(*pObjInfo)); 347 if (!pObjInfo) 348 return ERROR_NOT_ENOUGH_MEMORY; 349 RT_ZERO(*pObjInfo); 350 uint32_t cbObjInfo = sizeof(*pObjInfo); 351 352 int vrc = VbglR0SfFsInfo(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 353 SHFL_INFO_FILE | SHFL_INFO_GET, &cbObjInfo, (PSHFLDIRINFO)pObjInfo); 354 if (RT_SUCCESS(vrc)) 355 { 356 if (pSfFsi->sfi_mode & SFMODE_LARGE_FILE) 357 pSfFsi->sfi_sizel = pObjInfo->cbObject; 358 else 359 pSfFsi->sfi_sizel = RT_MIN(pObjInfo->cbObject, _2G - 1); 360 } 361 else 362 LogRel(("FS32_CHGFILEPTRL/CFP_RELEND: VbglR0SfFsInfo failed: %Rrc\n", vrc)); 363 VbglR0PhysHeapFree(pObjInfo); 364 365 offNew = pSfFsi->sfi_sizel + off; 366 if (offNew >= 0) 367 break; 368 Log(("FS32_CHGFILEPTRL: Negative seek (CFP_RELEND): %RI64 + %RI64\n", pSfFsi->sfi_sizel, off)); 369 return ERROR_NEGATIVE_SEEK; 370 } 371 372 373 default: 374 LogRel(("FS32_CHGFILEPTRL: Unknown seek method: %#x\n", uMethod)); 375 return ERROR_INVALID_FUNCTION; 376 } 377 378 /* 379 * Commit the seek. 380 */ 381 pSfFsi->sfi_positionl = offNew; 382 LogFlow(("FS32_CHGFILEPTRL: returns; sfi_positionl=%RI64\n", offNew)); 383 RT_NOREF_PV(fIoFlags); 384 return NO_ERROR; 75 385 } 76 386 77 387 78 388 /** Forwards the call to FS32_CHGFILEPTRL. */ 389 DECLASM(APIRET) 390 FS32_CHGFILEPTR(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, LONG off, ULONG uMethod, ULONG fIoFlags) 391 { 392 return FS32_CHGFILEPTRL(pSfFsi, pSfFsd, off, uMethod, fIoFlags); 393 } 394 395 396 /** 397 * Worker for FS32_PATHINFO that handles file stat setting. 398 * 399 * @returns OS/2 status code 400 * @param pFolder The folder. 401 * @param pSfFsi The file system independent file structure. We'll 402 * update the timestamps and size here. 403 * @param pSfFsd Out file data. 404 * @param uLevel The information level. 405 * @param pbData The stat data to set. 406 * @param cbData The uLevel specific input size. 407 */ 408 static APIRET 409 vboxSfOs2SetFileInfo(PVBOXSFFOLDER pFolder, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG uLevel, PBYTE pbData, ULONG cbData) 410 { 411 APIRET rc; 412 413 /* 414 * Data buffer both for caching user data and for issuing the 415 * change request to the host. 416 */ 417 struct SetFileInfoBuf 418 { 419 union 420 { 421 FILESTATUS Lvl1; 422 FILESTATUS3L Lvl1L; 423 }; 424 SHFLFSOBJINFO ObjInfo; 425 426 } *pBuf = (struct SetFileInfoBuf *)VbglR0PhysHeapAlloc(sizeof(*pBuf)); 427 if (pBuf) 428 { 429 /* Copy in the data. */ 430 rc = KernCopyIn(&pBuf->Lvl1, pbData, cbData); 431 if (rc == NO_ERROR) 432 { 433 /* 434 * Join paths with FS32_PATHINFO and FS32_FILEATTRIBUTE. 435 */ 436 rc = vboxSfOs2SetInfoCommonWorker(pFolder, pSfFsd->hHostFile, 437 uLevel == FI_LVL_STANDARD ? pBuf->Lvl1.attrFile : pBuf->Lvl1L.attrFile, 438 &pBuf->Lvl1, &pBuf->ObjInfo); 439 if (rc == NO_ERROR) 440 { 441 /* 442 * Update the timestamps in the independent file data with what 443 * the host returned: 444 */ 445 pSfFsi->sfi_tstamp |= ST_PCREAT | ST_PWRITE | ST_PREAD; 446 pSfFsi->sfi_tstamp &= ~(ST_SCREAT | ST_SWRITE| ST_SREAD); 447 uint16_t cDelta = vboxSfOs2GetLocalTimeDelta(); 448 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_cdate, &pSfFsi->sfi_ctime, pBuf->ObjInfo.BirthTime, cDelta); 449 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_adate, &pSfFsi->sfi_atime, pBuf->ObjInfo.AccessTime, cDelta); 450 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_mdate, &pSfFsi->sfi_mtime, pBuf->ObjInfo.ModificationTime, cDelta); 451 452 /* And the size field as we're at it: */ 453 pSfFsi->sfi_sizel = pBuf->ObjInfo.cbObject; 454 } 455 else 456 rc = ERROR_INVALID_PARAMETER; 457 } 458 459 VbglR0PhysHeapFree(pBuf); 460 } 461 else 462 rc = ERROR_NOT_ENOUGH_MEMORY; 463 return rc; 464 } 465 466 467 /** 468 * Worker for FS32_PATHINFO that handles file stat queries. 469 * 470 * @returns OS/2 status code 471 * @param pFolder The folder. 472 * @param pSfFsi The file system independent file structure. We'll 473 * update the timestamps and size here. 474 * @param pSfFsd Out file data. 475 * @param uLevel The information level. 476 * @param pbData Where to return the data (user address). 477 * @param cbData The amount of data to produce. 478 */ 479 static APIRET 480 vboxSfOs2QueryFileInfo(PVBOXSFFOLDER pFolder, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG uLevel, PBYTE pbData, ULONG cbData) 481 { 482 APIRET rc; 483 PSHFLFSOBJINFO pObjInfo = (PSHFLFSOBJINFO)VbglR0PhysHeapAlloc(sizeof(*pObjInfo)); 484 if (pObjInfo) 485 { 486 RT_ZERO(*pObjInfo); 487 uint32_t cbObjInfo = sizeof(*pObjInfo); 488 489 int vrc = VbglR0SfFsInfo(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 490 SHFL_INFO_FILE | SHFL_INFO_GET, &cbObjInfo, (PSHFLDIRINFO)pObjInfo); 491 if (RT_SUCCESS(vrc)) 492 { 493 rc = vboxSfOs2FileStatusFromObjInfo(pbData, cbData, uLevel, pObjInfo); 494 if (rc == NO_ERROR) 495 { 496 /* Update the timestamps in the independent file data: */ 497 int16_t cMinLocalTimeDelta = vboxSfOs2GetLocalTimeDelta(); 498 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_cdate, &pSfFsi->sfi_ctime, pObjInfo->BirthTime, cMinLocalTimeDelta); 499 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_adate, &pSfFsi->sfi_atime, pObjInfo->AccessTime, cMinLocalTimeDelta); 500 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_mdate, &pSfFsi->sfi_mtime, pObjInfo->ModificationTime, cMinLocalTimeDelta); 501 502 /* And the size field as we're at it: */ 503 pSfFsi->sfi_sizel = pObjInfo->cbObject; 504 } 505 } 506 else 507 { 508 Log(("vboxSfOs2QueryFileInfo: VbglR0SfFsInfo failed: %Rrc\n", vrc)); 509 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_GEN_FAILURE); 510 } 511 } 512 else 513 rc = ERROR_NOT_ENOUGH_MEMORY; 514 return rc; 515 } 516 517 518 DECLASM(APIRET) 519 FS32_FILEINFO(ULONG fFlags, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG uLevel, 520 PBYTE pbData, ULONG cbData, ULONG fIoFlags) 521 { 522 LogFlow(("FS32_FILEINFO: fFlags=%#x pSfFsi=%p pSfFsd=%p uLevel=%p pbData=%p cbData=%#x fIoFlags=%#x\n", 523 fFlags, pSfFsi, pSfFsd, uLevel, pbData, cbData, fIoFlags)); 524 525 /* 526 * Validate input. 527 */ 528 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 529 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 530 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 531 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 532 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 533 Assert(pFolder->cOpenFiles > 0); 534 535 /* 536 * Check the level. 537 * Note! See notes in FS32_PATHINFO. 538 */ 539 ULONG cbMinData; 540 switch (uLevel) 541 { 542 case FI_LVL_STANDARD: 543 cbMinData = sizeof(FILESTATUS); 544 AssertCompileSize(FILESTATUS, 0x16); 545 break; 546 case FI_LVL_STANDARD_64: 547 cbMinData = sizeof(FILESTATUS3L); 548 AssertCompileSize(FILESTATUS3L, 0x20); /* cbFile and cbFileAlloc are misaligned. */ 549 break; 550 case FI_LVL_STANDARD_EASIZE: 551 cbMinData = sizeof(FILESTATUS2); 552 AssertCompileSize(FILESTATUS2, 0x1a); 553 break; 554 case FI_LVL_STANDARD_EASIZE_64: 555 cbMinData = sizeof(FILESTATUS4L); 556 AssertCompileSize(FILESTATUS4L, 0x24); /* cbFile and cbFileAlloc are misaligned. */ 557 break; 558 case FI_LVL_EAS_FROM_LIST: 559 case FI_LVL_EAS_FULL: 560 case FI_LVL_EAS_FULL_5: 561 case FI_LVL_EAS_FULL_8: 562 cbMinData = sizeof(EAOP); 563 break; 564 default: 565 LogRel(("FS32_PATHINFO: Unsupported info level %u!\n", uLevel)); 566 return ERROR_INVALID_LEVEL; 567 } 568 if (cbData < cbMinData || pbData == NULL) 569 { 570 Log(("FS32_FILEINFO: ERROR_BUFFER_OVERFLOW (cbMinData=%#x, cbData=%#x)\n", cbMinData, cbData)); 571 return ERROR_BUFFER_OVERFLOW; 572 } 573 574 /* 575 * Query information. 576 */ 577 APIRET rc; 578 if (fFlags == FI_RETRIEVE) 579 { 580 switch (uLevel) 581 { 582 case FI_LVL_STANDARD: 583 case FI_LVL_STANDARD_EASIZE: 584 case FI_LVL_STANDARD_64: 585 case FI_LVL_STANDARD_EASIZE_64: 586 rc = vboxSfOs2QueryFileInfo(pFolder, pSfFsi, pSfFsd, uLevel, pbData, cbMinData); 587 break; 588 589 /* 590 * We don't do EAs and we "just" need to return no-EAs. 591 * However, that's not as easy as you might think. 592 */ 593 case FI_LVL_EAS_FROM_LIST: 594 case FI_LVL_EAS_FULL: 595 case FI_LVL_EAS_FULL_5: 596 case FI_LVL_EAS_FULL_8: 597 rc = vboxSfOs2MakeEmptyEaList((PEAOP)pbData, uLevel); 598 break; 599 600 default: 601 AssertFailed(); 602 rc = ERROR_GEN_FAILURE; 603 break; 604 } 605 } 606 /* 607 * Update information. 608 */ 609 else if (fFlags == FI_SET) 610 { 611 switch (uLevel) 612 { 613 case FI_LVL_STANDARD: 614 case FI_LVL_STANDARD_64: 615 rc = vboxSfOs2SetFileInfo(pFolder, pSfFsi, pSfFsd, uLevel, pbData, cbMinData); 616 break; 617 618 case FI_LVL_STANDARD_EASIZE: 619 rc = ERROR_EAS_NOT_SUPPORTED; 620 break; 621 622 case FI_LVL_STANDARD_EASIZE_64: 623 case FI_LVL_EAS_FROM_LIST: 624 case FI_LVL_EAS_FULL: 625 case FI_LVL_EAS_FULL_5: 626 case FI_LVL_EAS_FULL_8: 627 rc = ERROR_INVALID_LEVEL; 628 break; 629 630 default: 631 AssertFailed(); 632 rc = ERROR_GEN_FAILURE; 633 break; 634 } 635 } 636 else 637 { 638 LogRel(("FS32_FILEINFO: Unknown flags value: %#x\n", fFlags)); 639 rc = ERROR_INVALID_PARAMETER; 640 } 641 RT_NOREF_PV(fIoFlags); 642 return rc; 643 } 644 645 646 DECLASM(APIRET) 647 FS32_NEWSIZEL(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, LONGLONG cbFile, ULONG fIoFlags) 648 { 649 LogFlow(("FS32_NEWSIZEL: pSfFsi=%p pSfFsd=%p cbFile=%RI64 (%#RX64) fIoFlags=%#x\n", pSfFsi, pSfFsd, cbFile, cbFile, fIoFlags)); 650 651 /* 652 * Validate input. 653 */ 654 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 655 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 656 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 657 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 658 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 659 Assert(pFolder->cOpenFiles > 0); 660 if (cbFile < 0) 661 { 662 LogRel(("FS32_NEWSIZEL: Negative size: %RI64\n", cbFile)); 663 return ERROR_INVALID_PARAMETER; 664 } 665 666 /* 667 * This should only be possible on a file that is writable. 668 */ 669 APIRET rc; 670 if ( (pSfFsi->sfi_mode & SFMODE_OPEN_ACCESS) == SFMODE_OPEN_WRITEONLY 671 || (pSfFsi->sfi_mode & SFMODE_OPEN_ACCESS) == SFMODE_OPEN_READWRITE) 672 { 673 /* 674 * Call the host. We need a full object info structure here to pass 675 * a 64-bit unsigned integer value. Sigh. 676 */ 677 /** @todo Shared folders: New SET_FILE_SIZE API. */ 678 PSHFLFSOBJINFO pObjInfo = (PSHFLFSOBJINFO)VbglR0PhysHeapAlloc(sizeof(*pObjInfo)); 679 if (pObjInfo) 680 { 681 RT_ZERO(*pObjInfo); 682 pObjInfo->cbObject = cbFile; 683 uint32_t cbObjInfo = sizeof(*pObjInfo); 684 int vrc = VbglR0SfFsInfo(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 685 SHFL_INFO_SIZE | SHFL_INFO_SET, &cbObjInfo, (PSHFLDIRINFO)pObjInfo); 686 if (RT_SUCCESS(vrc)) 687 { 688 pSfFsi->sfi_sizel = cbFile; 689 rc = NO_ERROR; 690 } 691 else 692 { 693 LogRel(("FS32_NEWSIZEL: VbglR0SfFsInfo failed: %Rrc\n", vrc)); 694 if (vrc == VERR_DISK_FULL) 695 rc = ERROR_DISK_FULL; 696 else 697 rc = ERROR_GEN_FAILURE; 698 } 699 VbglR0PhysHeapFree(pObjInfo); 700 } 701 else 702 rc = ERROR_NOT_ENOUGH_MEMORY; 703 } 704 else 705 rc = ERROR_ACCESS_DENIED; 706 LogFlow(("FS32_NEWSIZEL: returns %u\n", rc)); 707 return rc; 708 } 709 710 79 711 extern "C" APIRET APIENTRY 80 FS32_CHGFILEPTR(PSFFSI psffsi, PVBOXSFFSD psffsd, LONG off, ULONG uMethod, ULONG fIoFlags) 81 { 82 return FS32_CHGFILEPTRL(psffsi, psffsd, off, uMethod, fIoFlags); 83 } 84 85 DECLASM(int) 86 FS32_FILEINFO(ULONG fFlag, PSFFSI psffsi, PVBOXSFFSD psffsd, ULONG uLevel, 87 PBYTE pbData, ULONG cbData, ULONG fIoFlags) 88 { 89 NOREF(fFlag); NOREF(psffsi); NOREF(psffsd); NOREF(uLevel); NOREF(pbData); NOREF(cbData); NOREF(fIoFlags); 90 return ERROR_NOT_SUPPORTED; 91 } 92 93 DECLASM(int) 94 FS32_NEWSIZEL(PSFFSI psffsi, PVBOXSFFSD psffsd, LONGLONG cbFile, ULONG fIoFlags) 95 { 96 NOREF(psffsi); NOREF(psffsd); NOREF(cbFile); NOREF(fIoFlags); 97 return ERROR_NOT_SUPPORTED; 712 FS32_READ(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, PVOID pvData, PULONG pcb, ULONG fIoFlags) 713 { 714 LogFlow(("FS32_READ: pSfFsi=%p pSfFsd=%p pvData=%p pcb=%p:{%#x} fIoFlags=%#x\n", pSfFsi, pSfFsd, pvData, pcb, *pcb, fIoFlags)); 715 716 /* 717 * Validate input. 718 */ 719 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 720 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 721 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 722 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 723 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 724 Assert(pFolder->cOpenFiles > 0); 725 RT_NOREF(pFolder); 726 727 /* 728 * If the read request is small enough, go thru a temporary buffer to 729 * avoid locking/unlocking user memory. 730 */ 731 uint64_t offRead = pSfFsi->sfi_positionl; 732 uint32_t cbRead = *pcb; 733 uint32_t cbActual = cbRead; 734 if (cbRead <= _8K - ALLOC_HDR_SIZE) 735 { 736 void *pvBuf = VbglR0PhysHeapAlloc(cbRead); 737 if (pvBuf != NULL) 738 { 739 APIRET rc; 740 int vrc = VbglR0SfRead(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 741 offRead, &cbActual, (uint8_t *)pvBuf, true /*fLocked*/); 742 if (RT_SUCCESS(vrc)) 743 { 744 AssertStmt(cbActual <= cbRead, cbActual = cbRead); 745 rc = KernCopyOut(pvData, pvBuf, cbActual); 746 if (rc == NO_ERROR) 747 { 748 *pcb = cbActual; 749 pSfFsi->sfi_positionl = offRead + cbActual; 750 if (pSfFsi->sfi_sizel < offRead + cbActual) 751 pSfFsi->sfi_sizel = offRead + cbActual; 752 pSfFsi->sfi_tstamp |= ST_SREAD | ST_PREAD; 753 LogFlow(("FS32_READ: returns; cbActual=%#x sfi_positionl=%RI64 [copy]\n", cbActual, pSfFsi->sfi_positionl)); 754 } 755 } 756 else 757 { 758 Log(("FS32_READ: VbglR0SfRead(off=%#x,cb=%#x) -> %Rrc [copy]\n", offRead, cbRead, vrc)); 759 rc = ERROR_BAD_NET_RESP; 760 } 761 VbglR0PhysHeapFree(pvBuf); 762 return rc; 763 } 764 } 765 766 /* 767 * Do the read directly on the buffer, Vbgl will do the locking for us. 768 */ 769 int vrc = VbglR0SfRead(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 770 offRead, &cbActual, (uint8_t *)pvData, false /*fLocked*/); 771 if (RT_SUCCESS(vrc)) 772 { 773 AssertStmt(cbActual <= cbRead, cbActual = cbRead); 774 *pcb = cbActual; 775 pSfFsi->sfi_positionl = offRead + cbActual; 776 if (pSfFsi->sfi_sizel < offRead + cbActual) 777 pSfFsi->sfi_sizel = offRead + cbActual; 778 pSfFsi->sfi_tstamp |= ST_SREAD | ST_PREAD; 779 LogFlow(("FS32_READ: returns; cbActual=%#x sfi_positionl=%RI64 [direct]\n", cbActual, pSfFsi->sfi_positionl)); 780 return NO_ERROR; 781 } 782 Log(("FS32_READ: VbglR0SfRead(off=%#x,cb=%#x) -> %Rrc [direct]\n", offRead, cbRead, vrc)); 783 RT_NOREF_PV(fIoFlags); 784 return ERROR_BAD_NET_RESP; 98 785 } 99 786 100 787 101 788 extern "C" APIRET APIENTRY 102 FS32_READ(PSFFSI psffsi, PVBOXSFFSD psffsd, PVOID pvData, PULONG pcb, ULONG fIoFlags) 103 { 104 NOREF(psffsi); NOREF(psffsd); NOREF(pvData); NOREF(pcb); NOREF(fIoFlags); 105 return ERROR_NOT_SUPPORTED; 789 FS32_WRITE(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, void const *pvData, PULONG pcb, ULONG fIoFlags) 790 { 791 /* 792 * Validate input. 793 */ 794 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 795 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 796 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 797 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 798 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 799 Assert(pFolder->cOpenFiles > 0); 800 RT_NOREF(pFolder); 801 802 /* 803 * If the write request is small enough, go thru a temporary buffer to 804 * avoid locking/unlocking user memory. 805 */ 806 uint64_t offWrite = pSfFsi->sfi_positionl; 807 uint32_t cbWrite = *pcb; 808 uint32_t cbActual = cbWrite; 809 if (cbWrite <= _8K - ALLOC_HDR_SIZE) 810 { 811 void *pvBuf = VbglR0PhysHeapAlloc(cbWrite); 812 if (pvBuf != NULL) 813 { 814 APIRET rc = KernCopyIn(pvBuf, pvData, cbWrite); 815 if (rc == NO_ERROR) 816 { 817 int vrc = VbglR0SfWrite(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 818 offWrite, &cbActual, (uint8_t *)pvBuf, true /*fLocked*/); 819 if (RT_SUCCESS(vrc)) 820 { 821 AssertStmt(cbActual <= cbWrite, cbActual = cbWrite); 822 *pcb = cbActual; 823 pSfFsi->sfi_positionl = offWrite + cbActual; 824 if (pSfFsi->sfi_sizel < offWrite + cbActual) 825 pSfFsi->sfi_sizel = offWrite + cbActual; 826 pSfFsi->sfi_tstamp |= ST_SWRITE | ST_PWRITE; 827 LogFlow(("FS32_READ: returns; cbActual=%#x sfi_positionl=%RI64 [copy]\n", cbActual, pSfFsi->sfi_positionl)); 828 } 829 else 830 { 831 Log(("FS32_READ: VbglR0SfWrite(off=%#x,cb=%#x) -> %Rrc [copy]\n", offWrite, cbWrite, vrc)); 832 rc = ERROR_BAD_NET_RESP; 833 } 834 } 835 VbglR0PhysHeapFree(pvBuf); 836 return rc; 837 } 838 } 839 840 /* 841 * Do the write directly on the buffer, Vbgl will do the locking for us. 842 */ 843 int vrc = VbglR0SfWrite(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 844 offWrite, &cbActual, (uint8_t *)pvData, false /*fLocked*/); 845 if (RT_SUCCESS(vrc)) 846 { 847 AssertStmt(cbActual <= cbWrite, cbActual = cbWrite); 848 *pcb = cbActual; 849 pSfFsi->sfi_positionl = offWrite + cbActual; 850 if (pSfFsi->sfi_sizel < offWrite + cbActual) 851 pSfFsi->sfi_sizel = offWrite + cbActual; 852 pSfFsi->sfi_tstamp |= ST_SWRITE | ST_PWRITE; 853 LogFlow(("FS32_READ: returns; cbActual=%#x sfi_positionl=%RI64 [direct]\n", cbActual, pSfFsi->sfi_positionl)); 854 return NO_ERROR; 855 } 856 Log(("FS32_READ: VbglR0SfWrite(off=%#x,cb=%#x) -> %Rrc [direct]\n", offWrite, cbWrite, vrc)); 857 RT_NOREF_PV(fIoFlags); 858 return ERROR_BAD_NET_RESP; 106 859 } 107 860 108 861 109 862 extern "C" APIRET APIENTRY 110 FS32_WRITE(PSFFSI psffsi, PVBOXSFFSD psffsd, PVOID pvData, PULONG pcb, ULONG fIoFlags) 111 { 112 NOREF(psffsi); NOREF(psffsd); NOREF(pvData); NOREF(pcb); NOREF(fIoFlags); 113 return ERROR_NOT_SUPPORTED; 114 } 115 116 117 extern "C" APIRET APIENTRY 118 FS32_READFILEATCACHE(PSFFSI psffsi, PVBOXSFFSD psffsd, ULONG fIoFlags, LONGLONG off, ULONG pcb, KernCacheList_t **ppCacheList) 119 { 120 NOREF(psffsi); NOREF(psffsd); NOREF(fIoFlags); NOREF(off); NOREF(pcb); NOREF(ppCacheList); 863 FS32_READFILEATCACHE(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG fIoFlags, LONGLONG off, ULONG pcb, KernCacheList_t **ppCacheList) 864 { 865 /* 866 * Validate input. 867 */ 868 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 869 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 870 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 871 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 872 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 873 Assert(pFolder->cOpenFiles > 0); 874 RT_NOREF(pFolder); 875 876 /* I think this is used for sendfile(). */ 877 878 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(fIoFlags); NOREF(off); NOREF(pcb); NOREF(ppCacheList); 121 879 return ERROR_NOT_SUPPORTED; 122 880 } … … 133 891 /* oddments */ 134 892 135 DECLASM(int) 136 FS32_CANCELLOCKREQUESTL(PSFFSI psffsi, PVBOXSFFSD psffsd, struct filelockl *pLockRange) 137 { 138 NOREF(psffsi); NOREF(psffsd); NOREF(pLockRange); 139 return ERROR_NOT_SUPPORTED; 140 } 141 142 143 DECLASM(int) 144 FS32_CANCELLOCKREQUEST(PSFFSI psffsi, PVBOXSFFSD psffsd, struct filelock *pLockRange) 145 { 146 NOREF(psffsi); NOREF(psffsd); NOREF(pLockRange); 147 return ERROR_NOT_SUPPORTED; 148 } 149 150 151 DECLASM(int) 152 FS32_FILELOCKSL(PSFFSI psffsi, PVBOXSFFSD psffsd, struct filelockl *pUnLockRange, 893 DECLASM(APIRET) 894 FS32_CANCELLOCKREQUESTL(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, struct filelockl *pLockRange) 895 { 896 /* 897 * Validate input. 898 */ 899 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 900 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 901 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 902 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 903 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 904 Assert(pFolder->cOpenFiles > 0); 905 RT_NOREF(pFolder); 906 907 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(pLockRange); 908 return ERROR_NOT_SUPPORTED; 909 } 910 911 912 DECLASM(APIRET) 913 FS32_CANCELLOCKREQUEST(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, struct filelock *pLockRange) 914 { 915 /* 916 * Validate input. 917 */ 918 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 919 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 920 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 921 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 922 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 923 Assert(pFolder->cOpenFiles > 0); 924 RT_NOREF(pFolder); 925 926 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(pLockRange); 927 return ERROR_NOT_SUPPORTED; 928 } 929 930 931 DECLASM(APIRET) 932 FS32_FILELOCKSL(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, struct filelockl *pUnLockRange, 153 933 struct filelockl *pLockRange, ULONG cMsTimeout, ULONG fFlags) 154 934 { 155 NOREF(psffsi); NOREF(psffsd); NOREF(pUnLockRange); NOREF(pLockRange); NOREF(cMsTimeout); NOREF(fFlags); 156 return ERROR_NOT_SUPPORTED; 157 } 158 159 160 DECLASM(int) 161 FS32_FILELOCKS(PSFFSI psffsi, PVBOXSFFSD psffsd, struct filelock *pUnLockRange, 935 /* 936 * Validate input. 937 */ 938 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 939 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 940 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 941 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 942 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 943 Assert(pFolder->cOpenFiles > 0); 944 RT_NOREF(pFolder); 945 946 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(pUnLockRange); NOREF(pLockRange); NOREF(cMsTimeout); NOREF(fFlags); 947 return ERROR_NOT_SUPPORTED; 948 } 949 950 951 DECLASM(APIRET) 952 FS32_FILELOCKS(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, struct filelock *pUnLockRange, 162 953 struct filelock *pLockRange, ULONG cMsTimeout, ULONG fFlags) 163 954 { 164 NOREF(psffsi); NOREF(psffsd); NOREF(pUnLockRange); NOREF(pLockRange); NOREF(cMsTimeout); NOREF(fFlags); 165 return ERROR_NOT_SUPPORTED; 166 } 167 168 169 DECLASM(int) 170 FS32_IOCTL(PSFFSI psffsi, PVBOXSFFSD psffsd, USHORT uCategory, USHORT uFunction, 955 /* 956 * Validate input. 957 */ 958 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 959 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 960 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 961 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 962 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 963 Assert(pFolder->cOpenFiles > 0); 964 RT_NOREF(pFolder); 965 966 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(pUnLockRange); NOREF(pLockRange); NOREF(cMsTimeout); NOREF(fFlags); 967 return ERROR_NOT_SUPPORTED; 968 } 969 970 971 DECLASM(APIRET) 972 FS32_IOCTL(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, USHORT uCategory, USHORT uFunction, 171 973 PVOID pvParm, USHORT cbParm, PUSHORT pcbParmIO, 172 974 PVOID pvData, USHORT cbData, PUSHORT pcbDataIO) 173 975 { 174 NOREF(psffsi); NOREF(psffsd); NOREF(uCategory); NOREF(uFunction); NOREF(pvParm); NOREF(cbParm); NOREF(pcbParmIO); 976 /* 977 * Validate input. 978 */ 979 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 980 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 981 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 982 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 983 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 984 Assert(pFolder->cOpenFiles > 0); 985 RT_NOREF(pFolder); 986 987 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(uCategory); NOREF(uFunction); NOREF(pvParm); NOREF(cbParm); NOREF(pcbParmIO); 175 988 NOREF(pvData); NOREF(cbData); NOREF(pcbDataIO); 176 989 return ERROR_NOT_SUPPORTED; … … 178 991 179 992 180 DECLASM( int)181 FS32_FILEIO(PSFFSI p sffsi, PVBOXSFFSD psffsd, PBYTE pbCmdList, USHORT cbCmdList,993 DECLASM(APIRET) 994 FS32_FILEIO(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, PBYTE pbCmdList, USHORT cbCmdList, 182 995 PUSHORT poffError, USHORT fIoFlag) 183 996 { 184 NOREF(psffsi); NOREF(psffsd); NOREF(pbCmdList); NOREF(cbCmdList); NOREF(poffError); NOREF(fIoFlag); 185 return ERROR_NOT_SUPPORTED; 186 } 187 188 189 DECLASM(int) 190 FS32_NMPIPE(PSFFSI psffsi, PVBOXSFFSD psffsd, USHORT uOpType, union npoper *pOpRec, 997 /* 998 * Validate input. 999 */ 1000 AssertReturn(pSfFsd->u32Magic == VBOXSFSYFI_MAGIC, ERROR_SYS_INTERNAL); 1001 AssertReturn(pSfFsd->pSelf == pSfFsd, ERROR_SYS_INTERNAL); 1002 PVBOXSFFOLDER pFolder = pSfFsd->pFolder; 1003 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 1004 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 1005 Assert(pFolder->cOpenFiles > 0); 1006 RT_NOREF(pFolder); 1007 1008 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(pbCmdList); NOREF(cbCmdList); NOREF(poffError); NOREF(fIoFlag); 1009 return ERROR_NOT_SUPPORTED; 1010 } 1011 1012 1013 DECLASM(APIRET) 1014 FS32_NMPIPE(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, USHORT uOpType, union npoper *pOpRec, 191 1015 PBYTE pbData, PCSZ pszName) 192 1016 { 193 NOREF(p sffsi); NOREF(psffsd); NOREF(uOpType); NOREF(pOpRec); NOREF(pbData); NOREF(pszName);194 return ERROR_NOT_SUPPORTED; 195 } 196 197 198 DECLASM( int)199 FS32_OPENPAGEFILE(PULONG pfFlags, PULONG pcMaxReq, PCSZ pszName, PSFFSI p sffsi, PVBOXSFFSD psffsd,200 USHORT uOpenMode, USHORT fOpenFlags, USHORT fAttr, ULONG uReserved)201 { 202 NOREF(pfFlags); NOREF(pcMaxReq); NOREF(pszName); NOREF(p sffsi); NOREF(psffsd); NOREF(uOpenMode); NOREF(fOpenFlags);1017 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(uOpType); NOREF(pOpRec); NOREF(pbData); NOREF(pszName); 1018 return ERROR_NOT_SUPPORTED; 1019 } 1020 1021 1022 DECLASM(APIRET) 1023 FS32_OPENPAGEFILE(PULONG pfFlags, PULONG pcMaxReq, PCSZ pszName, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, 1024 USHORT fOpenMode, USHORT fOpenFlags, USHORT fAttr, ULONG uReserved) 1025 { 1026 NOREF(pfFlags); NOREF(pcMaxReq); NOREF(pszName); NOREF(pSfFsi); NOREF(pSfFsd); NOREF(fOpenMode); NOREF(fOpenFlags); 203 1027 NOREF(fAttr); NOREF(uReserved); 204 1028 return ERROR_NOT_SUPPORTED; … … 206 1030 207 1031 208 DECLASM( int)209 FS32_SETSWAP(PSFFSI p sffsi, PVBOXSFFSD psffsd)210 { 211 NOREF(p sffsi); NOREF(psffsd);212 return ERROR_NOT_SUPPORTED; 213 } 214 215 216 DECLASM( int)217 FS32_ALLOCATEPAGESPACE(PSFFSI p sffsi, PVBOXSFFSD psffsd, ULONG cb, USHORT cbWantContig)218 { 219 NOREF(p sffsi); NOREF(psffsd); NOREF(cb); NOREF(cbWantContig);220 return ERROR_NOT_SUPPORTED; 221 } 222 223 224 DECLASM( int)225 FS32_DOPAGEIO(PSFFSI p sffsi, PVBOXSFFSD psffsd, struct PageCmdHeader *pList)226 { 227 NOREF(p sffsi); NOREF(psffsd); NOREF(pList);228 return ERROR_NOT_SUPPORTED; 229 } 230 1032 DECLASM(APIRET) 1033 FS32_SETSWAP(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd) 1034 { 1035 NOREF(pSfFsi); NOREF(pSfFsd); 1036 return ERROR_NOT_SUPPORTED; 1037 } 1038 1039 1040 DECLASM(APIRET) 1041 FS32_ALLOCATEPAGESPACE(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG cb, USHORT cbWantContig) 1042 { 1043 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(cb); NOREF(cbWantContig); 1044 return ERROR_NOT_SUPPORTED; 1045 } 1046 1047 1048 DECLASM(APIRET) 1049 FS32_DOPAGEIO(PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, struct PageCmdHeader *pList) 1050 { 1051 NOREF(pSfFsi); NOREF(pSfFsd); NOREF(pList); 1052 return ERROR_NOT_SUPPORTED; 1053 } 1054 -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFFind.cpp
r68612 r75337 5 5 6 6 /* 7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>7 * Copyright (c) 2007-2018 knut st. osmundsen <[email protected]> 8 8 * 9 9 * Permission is hereby granted, free of charge, to any person … … 37 37 38 38 #include <VBox/log.h> 39 #include <iprt/asm.h> 39 40 #include <iprt/assert.h> 40 41 42 DECLASM(int) 43 FS32_FINDFIRST(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszName, USHORT iCurDirEnd, USHORT fAttr, 44 PFSFSI pfsfsi, PVBOXSFFS pfsfsd, PBYTE pbData, USHORT cbData, PUSHORT pcMatch, 45 USHORT uLevel, USHORT fFlags) 46 { 47 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszName); NOREF(iCurDirEnd); NOREF(fAttr); NOREF(pfsfsi); NOREF(pfsfsd); NOREF(pbData); 48 NOREF(cbData); NOREF(pcMatch); NOREF(uLevel); NOREF(fFlags); 41 #include <iprt/mem.h> 42 #include <iprt/path.h> 43 #include <iprt/err.h> 44 45 46 47 /** 48 * Checks if the given name is 8-dot-3 compatible. 49 * 50 * @returns true if compatible, false if not. 51 * @param pszName The name to inspect (UTF-8). 52 */ 53 static bool vboxSfOs2IsUtf8Name8dot3(const char *pszName, size_t cchName, PRTUTF16 pwszTmp, size_t cwcTmp) 54 { 55 /* Reject names that must be too long when using maximum UTF-8 encoding. */ 56 if (cchName > (8 + 1 + 3) * 4) 57 return false; 58 59 /* First char cannot be a dot. */ 60 if (*pszName == '.' || !*pszName) 61 return false; 62 63 /* 64 * To basic checks on code point level before doing full conversion. 65 */ 66 const char *pszCursor = pszName; 67 for (uint32_t cuc = 0; ; cuc++) 68 { 69 RTUNICP uCp; 70 RTStrGetCpEx(&pszCursor, &uCp); 71 if (uCp == '.') 72 { 73 for (uint32_t cuc = 0; ; cuc++) 74 { 75 RTUNICP uCp; 76 RTStrGetCpEx(&pszCursor, &uCp); 77 if (!uCp) 78 break; 79 if (uCp == '.') 80 return false; 81 if (cuc >= 3) 82 return false; 83 } 84 break; 85 } 86 if (!uCp) 87 break; 88 if (cuc >= 8) 89 return false; 90 } 91 92 /* 93 * Convert to UTF-16 and then to native codepage. 94 */ 95 size_t cwcActual = cwcTmp; 96 int rc = RTStrToUtf16Ex(pszName, cchName, &pwszTmp, cwcTmp, &cwcActual); 97 if (RT_SUCCESS(rc)) 98 { 99 char *pszTmp = (char *)&pwszTmp[cwcActual + 1]; 100 rc = KernStrFromUcs(NULL, pszTmp, pwszTmp, (cwcTmp - cwcActual - 1) * sizeof(RTUTF16), cwcActual); 101 if (rc != NO_ERROR) 102 { 103 LogRel(("vboxSfOs2IsUtf8Name8dot3: KernStrFromUcs failed: %d\n", rc)); 104 return false; 105 } 106 107 /* 108 * Redo the check. 109 * Note! This could be bogus if a DBCS leadin sequence collides with '.'. 110 */ 111 for (uint32_t cch = 0; ; cch++) 112 { 113 char ch = *pszTmp++; 114 if (ch == '.') 115 break; 116 if (ch == '\0') 117 return true; 118 if (cch >= 8) 119 return false; 120 } 121 for (uint32_t cch = 0; ; cch++) 122 { 123 char ch = *pszTmp++; 124 if (ch == '\0') 125 return true; 126 if (ch != '.') 127 return false; 128 if (cch >= 3) 129 return false; 130 } 131 } 132 else 133 LogRel(("vboxSfOs2IsUtf8Name8dot3: RTStrToUtf16Ex failed: %Rrc\n", rc)); 134 return false; 135 } 136 137 138 /** 139 * @returns Updated pbDst on success, NULL on failure. 140 */ 141 static uint8_t *vboxSfOs2CopyUtf8Name(uint8_t *pbDst, PRTUTF16 pwszTmp, size_t cwcTmp, const char *pszSrc, size_t cchSrc) 142 { 143 /* Convert UTF-8 to UTF-16: */ 144 int rc = RTStrToUtf16Ex(pszSrc, cchSrc, &pwszTmp, cwcTmp, &cwcTmp); 145 if (RT_SUCCESS(rc)) 146 { 147 char *pszDst = (char *)(pbDst + 1); 148 rc = KernStrFromUcs(NULL, pszDst, pwszTmp, CCHMAXPATHCOMP, cwcTmp); 149 if (rc == NO_ERROR) 150 { 151 size_t cchDst = strlen(pszDst); 152 *pbDst++ = (uint8_t)cchDst; 153 pbDst += cchDst; 154 *pbDst++ = '\0'; 155 return pbDst; 156 } 157 LogRel(("vboxSfOs2CopyUtf8Name: KernStrFromUcs failed: %d\n", rc)); 158 } 159 else 160 LogRel(("vboxSfOs2CopyUtf8Name: RTStrToUtf16Ex failed: %Rrc\n", rc)); 161 return NULL; 162 } 163 164 165 /** 166 * @returns Updated pbDst on success, NULL on failure. 167 */ 168 static uint8_t *vboxSfOs2CopyUtf8NameAndUpperCase(uint8_t *pbDst, PRTUTF16 pwszTmp, size_t cwcTmp, const char *pszSrc, size_t cchSrc) 169 { 170 /* Convert UTF-8 to UTF-16: */ 171 int rc = RTStrToUtf16Ex(pszSrc, cchSrc, &pwszTmp, cwcTmp, &cwcTmp); 172 if (RT_SUCCESS(rc)) 173 { 174 char *pszDst = (char *)(pbDst + 1); 175 rc = KernStrFromUcs(NULL, pszDst, RTUtf16ToUpper(pwszTmp), CCHMAXPATHCOMP, cwcTmp); 176 if (rc == NO_ERROR) 177 { 178 size_t cchDst = strlen(pszDst); 179 *pbDst++ = (uint8_t)cchDst; 180 pbDst += cchDst; 181 *pbDst++ = '\0'; 182 return pbDst; 183 } 184 LogRel(("vboxSfOs2CopyUtf8NameAndUpperCase: KernStrFromUcs failed: %d\n", rc)); 185 } 186 else 187 LogRel(("vboxSfOs2CopyUtf8NameAndUpperCase: RTStrToUtf16Ex failed: %Rrc\n", rc)); 188 return NULL; 189 } 190 191 192 /** 193 * @returns Updated pbDst on success, NULL on failure. 194 */ 195 static uint8_t *vboxSfOs2CopyUtf16NameAndUpperCase(uint8_t *pbDst, PRTUTF16 pwszSrc, size_t cwcSrc) 196 { 197 char *pszDst = (char *)(pbDst + 1); 198 APIRET rc = KernStrFromUcs(NULL, pszDst, RTUtf16ToUpper(pwszSrc), CCHMAXPATHCOMP, cwcSrc); 199 if (rc == NO_ERROR) 200 { 201 size_t cchDst = strlen(pszDst); 202 *pbDst++ = (uint8_t)cchDst; 203 pbDst += cchDst; 204 *pbDst++ = '\0'; 205 return pbDst; 206 } 207 LogRel(("vboxSfOs2CopyUtf16NameAndUpperCase: KernStrFromUcs failed: %#x\n", rc)); 208 return NULL; 209 } 210 211 212 213 /** 214 * Worker for FS32_FINDFIRST, FS32_FINDNEXT and FS32_FINDFROMNAME. 215 * 216 * @returns OS/2 status code. 217 * @param pFolder The folder we're working on. 218 * @param pFsFsd The search handle data. 219 * @param pDataBuf The search data buffer (some handle data there too). 220 * @param uLevel The info level to return. 221 * @param fFlags Position flag. 222 * @param pbData The output buffer. 223 * @param cbData The size of the output buffer. 224 * @param cMaxMatches The maximum number of matches to return. 225 * @param pcMatches Where to set the number of returned matches. 226 */ 227 static APIRET vboxSfOs2ReadDirEntries(PVBOXSFFOLDER pFolder, PVBOXSFFS pFsFsd, PVBOXSFFSBUF pDataBuf, ULONG uLevel, ULONG fFlags, 228 PBYTE pbData, ULONG cbData, USHORT cMaxMatches, PUSHORT pcMatches) 229 { 230 APIRET rc = NO_ERROR; 231 232 /* 233 * If we're doing EAs, the buffer starts with an EAOP structure. 234 */ 235 EAOP EaOp; 236 PEAOP pEaOpUser; 237 switch (uLevel) 238 { 239 case FI_LVL_EAS_FROM_LIST: 240 case FI_LVL_EAS_FROM_LIST_64: 241 case FI_LVL_EAS_FULL: 242 case FI_LVL_EAS_FULL_5: 243 case FI_LVL_EAS_FULL_8: 244 if (cbData >= sizeof(EaOp)) 245 { 246 rc = KernCopyIn(&EaOp, pbData, sizeof(EaOp)); 247 if (rc == NO_ERROR) 248 { 249 EaOp.fpGEAList = (PGEALIST)KernSelToFlat((uintptr_t)EaOp.fpGEAList); 250 EaOp.fpFEAList = NULL; 251 252 pEaOpUser = (PEAOP)pbData; 253 pbData += sizeof(*pEaOpUser); 254 cbData -= sizeof(*pEaOpUser); 255 break; 256 } 257 } 258 else 259 rc = ERROR_BUFFER_OVERFLOW; 260 Log(("vboxSfOs2ReadDirEntries: Failed to read EAOP: %u\n", rc)); 261 return rc; 262 } 263 264 /* 265 * Do the reading. 266 */ 267 USHORT cMatches; 268 for (cMatches = 0; cMatches < cMaxMatches;) 269 { 270 /* 271 * Do we need to fetch more directory entries? 272 */ 273 PSHFLDIRINFO pEntry = pDataBuf->pEntry; 274 if ( pDataBuf->cEntriesLeft == 0 275 || pEntry == NULL /* paranoia */) 276 { 277 pDataBuf->pEntry = pEntry = (PSHFLDIRINFO)(pDataBuf + 1); 278 pDataBuf->cbValid = pDataBuf->cbBuf - sizeof(*pDataBuf); 279 int vrc = VbglR0SfDirInfo(&g_SfClient, &pFolder->hHostFolder, pFsFsd->hHostDir, pDataBuf->pFilter, 280 cMaxMatches == 1 ? SHFL_LIST_RETURN_ONE : 0, 0 /*index*/, &pDataBuf->cbValid, 281 pEntry, &pDataBuf->cEntriesLeft); 282 if (RT_SUCCESS(vrc)) 283 { 284 AssertReturn(pDataBuf->cbValid >= RT_UOFFSETOF(SHFLDIRINFO, name.String), ERROR_SYS_INTERNAL); 285 AssertReturn(pDataBuf->cbValid >= RT_UOFFSETOF(SHFLDIRINFO, name.String) + pEntry->name.u16Size, ERROR_SYS_INTERNAL); 286 Log4(("vboxSfOs2ReadDirEntries: VbglR0SfDirInfo returned %#x matches in %#x bytes\n", pDataBuf->cEntriesLeft, pDataBuf->cbValid)); 287 } 288 else 289 { 290 if (vrc == VERR_NO_MORE_FILES) 291 Log(("vboxSfOs2ReadDirEntries: VbglR0SfDirInfo failed %Rrc (%d,%d)\n", vrc, pDataBuf->cEntriesLeft, pDataBuf->cbValid)); 292 else 293 Log4(("vboxSfOs2ReadDirEntries: VbglR0SfDirInfo returned VERR_NO_MORE_FILES (%d,%d)\n", pDataBuf->cEntriesLeft, pDataBuf->cbValid)); 294 pDataBuf->pEntry = NULL; 295 pDataBuf->cEntriesLeft = 0; 296 if (cMatches == 0) 297 { 298 if (vrc == VERR_NO_MORE_FILES) 299 rc = ERROR_NO_MORE_FILES; 300 else 301 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_GEN_FAILURE); 302 } 303 break; 304 } 305 } 306 307 /* 308 * Do matching and stuff the return buffer. 309 */ 310 if ( !((pEntry->Info.Attr.fMode >> RTFS_DOS_SHIFT) & pDataBuf->fExcludedAttribs) 311 && ((pEntry->Info.Attr.fMode >> RTFS_DOS_SHIFT) & pDataBuf->fMustHaveAttribs) == pDataBuf->fMustHaveAttribs 312 && ( pDataBuf->fLongFilenames 313 || pEntry->cucShortName 314 || vboxSfOs2IsUtf8Name8dot3((char *)pEntry->name.String.utf8, pEntry->name.u16Length, 315 pDataBuf->wszTmp, sizeof(pDataBuf->wszTmp)))) 316 { 317 /* 318 * We stages all but FEAs (level 3, 4, 13 and 14). 319 */ 320 PBYTE const pbUserBufStart = pbData; /* In case we need to skip a bad name. */ 321 uint8_t *pbToCopy = pDataBuf->abStaging; 322 uint8_t *pbDst = pbToCopy; 323 324 /* Position (originally used for FS32_FINDFROMNAME 'position', but since reused 325 for FILEFINDBUF3::oNextEntryOffset and FILEFINDBUF4::oNextEntryOffset): */ 326 if (fFlags & FF_GETPOS) 327 { 328 *(uint32_t *)pbDst = pFsFsd->offLastFile + 1; 329 pbDst += sizeof(uint32_t); 330 } 331 332 /* Dates: Creation, Access, Write */ 333 vboxSfOs2DateTimeFromTimeSpec((FDATE *)pbDst, (FTIME *)(pbDst + 2), pEntry->Info.BirthTime, pDataBuf->cMinLocalTimeDelta); 334 pbDst += sizeof(FDATE) + sizeof(FTIME); 335 vboxSfOs2DateTimeFromTimeSpec((FDATE *)pbDst, (FTIME *)(pbDst + 2), pEntry->Info.AccessTime, pDataBuf->cMinLocalTimeDelta); 336 pbDst += sizeof(FDATE) + sizeof(FTIME); 337 vboxSfOs2DateTimeFromTimeSpec((FDATE *)pbDst, (FTIME *)(pbDst + 2), pEntry->Info.ModificationTime, pDataBuf->cMinLocalTimeDelta); 338 pbDst += sizeof(FDATE) + sizeof(FTIME); 339 340 /* File size, allocation size, attributes: */ 341 if (uLevel >= FI_LVL_STANDARD_64) 342 { 343 *(uint64_t *)pbDst = pEntry->Info.cbObject; 344 pbDst += sizeof(uint64_t); 345 *(uint64_t *)pbDst = pEntry->Info.cbAllocated; 346 pbDst += sizeof(uint64_t); 347 *(uint32_t *)pbDst = (pEntry->Info.Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT; 348 pbDst += sizeof(uint32_t); 349 } 350 else 351 { 352 *(uint32_t *)pbDst = (uint32_t)RT_MIN(pEntry->Info.cbObject, _2G - 1); 353 pbDst += sizeof(uint32_t); 354 *(uint32_t *)pbDst = (uint32_t)RT_MIN(pEntry->Info.cbAllocated, _2G - 1); 355 pbDst += sizeof(uint32_t); 356 *(uint16_t *)pbDst = (uint16_t)((pEntry->Info.Attr.fMode & RTFS_DOS_MASK_OS2) >> RTFS_DOS_SHIFT); 357 pbDst += sizeof(uint16_t); /* (Curious: Who is expanding this to 32-bits for 32-bit callers? */ 358 } 359 360 /* Extra EA related fields: */ 361 if ( uLevel == FI_LVL_STANDARD 362 || uLevel == FI_LVL_STANDARD_64) 363 { /* nothing */ } 364 else if ( uLevel == FI_LVL_STANDARD_EASIZE 365 || uLevel == FI_LVL_STANDARD_EASIZE_64) 366 { 367 /* EA size: */ 368 *(uint32_t *)pbDst = 0; 369 pbDst += sizeof(uint32_t); 370 } 371 else 372 { 373 /* Empty FEALIST - flush pending data first: */ 374 uint32_t cbToCopy = pbDst - pbToCopy; 375 if (cbToCopy < cbData) 376 { 377 rc = KernCopyOut(pbData, pbToCopy, cbToCopy); 378 if (rc == NO_ERROR) 379 { 380 pbData += cbToCopy; 381 cbData -= cbToCopy; 382 pbDst = pbToCopy; 383 384 uint32_t cbWritten = 0; 385 EaOp.fpFEAList = (PFEALIST)pbData; 386 rc = vboxSfOs2MakeEmptyEaListEx(&EaOp, uLevel, &cbWritten, &pEaOpUser->oError); 387 if (rc == NO_ERROR) 388 { 389 cbData -= cbWritten; 390 pbData += cbWritten; 391 } 392 } 393 } 394 else 395 rc = ERROR_BUFFER_OVERFLOW; 396 if (rc != NO_ERROR) 397 break; 398 } 399 400 /* The length prefixed filename. */ 401 if (pDataBuf->fLongFilenames) 402 pbDst = vboxSfOs2CopyUtf8Name(pbDst, pDataBuf->wszTmp, sizeof(pDataBuf->wszTmp), 403 (char *)pEntry->name.String.utf8, pEntry->name.u16Length); 404 else if (pEntry->cucShortName == 0) 405 pbDst = vboxSfOs2CopyUtf8NameAndUpperCase(pbDst, pDataBuf->wszTmp, sizeof(pDataBuf->wszTmp), 406 (char *)pEntry->name.String.utf8, pEntry->name.u16Length); 407 else 408 pbDst = vboxSfOs2CopyUtf16NameAndUpperCase(pbDst, pEntry->uszShortName, pEntry->cucShortName); 409 if (pbDst) 410 { 411 /* 412 * Copy out the staged data. 413 */ 414 uint32_t cbToCopy = pbDst - pbToCopy; 415 if (cbToCopy <= cbData) 416 { 417 rc = KernCopyOut(pbData, pbToCopy, cbToCopy); 418 if (rc == NO_ERROR) 419 { 420 Log4(("vboxSfOs2ReadDirEntries: match #%u LB %#x: '%s'\n", cMatches, cbToCopy, pEntry->name.String.utf8)); 421 Log4(("%.*Rhxd\n", cbToCopy, pbToCopy)); 422 423 pbData += cbToCopy; 424 cbData -= cbToCopy; 425 pbDst = pbToCopy; 426 427 cMatches++; 428 pFsFsd->offLastFile++; 429 } 430 else 431 break; 432 } 433 else 434 { 435 rc = ERROR_BUFFER_OVERFLOW; 436 break; 437 } 438 } 439 else 440 { 441 /* Name conversion issue, just skip the entry. */ 442 Log3(("vboxSfOs2ReadDirEntries: Skipping '%s' due to name conversion issue.\n", pEntry->name.String.utf8)); 443 cbData -= pbUserBufStart - pbData; 444 pbData = pbUserBufStart; 445 } 446 } 447 else 448 Log3(("vboxSfOs2ReadDirEntries: fMode=%#x filter out by %#x/%#x; '%s'\n", 449 pEntry->Info.Attr.fMode, pDataBuf->fMustHaveAttribs, pDataBuf->fExcludedAttribs, pEntry->name.String.utf8)); 450 451 /* 452 * Advance to the next directory entry from the host. 453 */ 454 if (pDataBuf->cEntriesLeft-- > 1) 455 { 456 pDataBuf->pEntry = pEntry = (PSHFLDIRINFO)&pEntry->name.String.utf8[pEntry->name.u16Size]; 457 uintptr_t offEntry = (uintptr_t)pEntry - (uintptr_t)(pDataBuf + 1); 458 AssertMsgReturn(offEntry + RT_UOFFSETOF(SHFLDIRINFO, name.String) <= pDataBuf->cbValid, 459 ("offEntry=%#x cbValid=%#x\n", offEntry, pDataBuf->cbValid), ERROR_SYS_INTERNAL); 460 AssertMsgReturn(offEntry + RT_UOFFSETOF(SHFLDIRINFO, name.String) + pEntry->name.u16Size <= pDataBuf->cbValid, 461 ("offEntry=%#x cbValid=%#x\n", offEntry, pDataBuf->cbValid), ERROR_SYS_INTERNAL); 462 } 463 else 464 pDataBuf->pEntry = NULL; 465 } 466 467 *pcMatches = cMatches; 468 469 /* Ignore buffer overflows if we've got matches to return. */ 470 if (rc == ERROR_BUFFER_OVERFLOW && cMatches > 0) 471 rc = NO_ERROR; 472 return rc; 473 } 474 475 476 DECLASM(APIRET) 477 FS32_FINDFIRST(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszPath, LONG offCurDirEnd, ULONG fAttribs, 478 PFSFSI pFsFsi, PVBOXSFFS pFsFsd, PBYTE pbData, ULONG cbData, PUSHORT pcMatches, ULONG uLevel, ULONG fFlags) 479 { 480 LogFlow(("pCdFsi=%p pCdFsd=%p pszPath=%p:{%s} offCurDirEnd=%d fAttribs=%#x pFsFsi=%p pFsFsd=%p pbData=%p cbData=%#x pcMatches=%p:{%#x} uLevel=%#x fFlags=%#x\n", 481 pCdFsi, pCdFsd, pszPath, pszPath, offCurDirEnd, fAttribs, pFsFsi, pFsFsd, pbData, cbData, pcMatches, *pcMatches, uLevel, fFlags)); 482 USHORT const cMaxMatches = *pcMatches; 483 *pcMatches = 0; 484 485 /* 486 * Input validation. 487 */ 488 switch (uLevel) 489 { 490 case FI_LVL_STANDARD: 491 case FI_LVL_STANDARD_64: 492 case FI_LVL_STANDARD_EASIZE: 493 case FI_LVL_STANDARD_EASIZE_64: 494 break; 495 496 case FI_LVL_EAS_FROM_LIST: 497 case FI_LVL_EAS_FROM_LIST_64: 498 if (cbData < sizeof(EAOP)) 499 { 500 Log(("FS32_FINDFIRST: Buffer smaller than EAOP: %#x\n", cbData)); 501 return ERROR_BUFFER_OVERFLOW; 502 } 503 break; 504 505 default: 506 LogRel(("FS32_FINDFIRST: Unsupported info level %u!\n", uLevel)); 507 return ERROR_INVALID_LEVEL; 508 } 509 510 /* 511 * Resolve path to a folder and folder relative path. 512 */ 513 PVBOXSFFOLDER pFolder; 514 PSHFLSTRING pStrFolderPath; 515 RT_NOREF(pCdFsi); 516 APIRET rc = vboxSfOs2ResolvePath(pszPath, pCdFsd, offCurDirEnd, &pFolder, &pStrFolderPath); 517 LogFlow(("FS32_FINDFIRST: vboxSfOs2ResolvePath: -> %u pFolder=%p\n", rc, pFolder)); 518 if (rc == NO_ERROR) 519 { 520 /* 521 * Look for a wildcard filter at the end of the path, saving it all for 522 * later in NT filter speak if present. 523 */ 524 PSHFLSTRING pFilter = NULL; 525 char *pszFilter = RTPathFilename((char *)pStrFolderPath->String.utf8); 526 if ( pszFilter 527 && ( strchr(pszFilter, '*') != NULL 528 || strchr(pszFilter, '?') != NULL)) 529 { 530 if (strcmp(pszFilter, "*.*") == 0) 531 { 532 /* All files, no filtering needed. Just drop the filter expression from the directory path. */ 533 *pszFilter = '\0'; 534 pStrFolderPath->u16Length = (uint16_t)((uint8_t *)pszFilter - &pStrFolderPath->String.utf8[0]); 535 } 536 else 537 { 538 /* Duplicate the whole path. */ 539 pFilter = vboxSfOs2StrDup(pStrFolderPath->String.ach, pStrFolderPath->u16Length); 540 if (pFilter) 541 { 542 /* Drop filter from directory path. */ 543 *pszFilter = '\0'; 544 pStrFolderPath->u16Length = (uint16_t)((uint8_t *)pszFilter - &pStrFolderPath->String.utf8[0]); 545 546 /* Convert filter part of the copy to NT speak. */ 547 pszFilter = (char *)&pFilter->String.utf8[(uint8_t *)pszFilter - &pStrFolderPath->String.utf8[0]]; 548 for (;;) 549 { 550 char ch = *pszFilter; 551 if (ch == '?') 552 *pszFilter = '>'; /* The DOS question mark: Matches one char, but dots and end-of-name eats them. */ 553 else if (ch == '.') 554 { 555 char ch2 = pszFilter[1]; 556 if (ch2 == '*' || ch2 == '?') 557 *pszFilter = '"'; /* The DOS dot: Matches a dot or end-of-name. */ 558 } 559 else if (ch == '*') 560 { 561 if (pszFilter[1] == '.') 562 *pszFilter = '<'; /* The DOS star: Matches zero or more chars except the DOS dot.*/ 563 } 564 else if (ch == '\0') 565 break; 566 pszFilter++; 567 } 568 } 569 else 570 rc = ERROR_NOT_ENOUGH_MEMORY; 571 } 572 } 573 /* 574 * When no wildcard is specified, we're supposed to return a single entry 575 * with the name in the final component. Exception is the root, where we 576 * always list the whole thing. 577 * 578 * Not sure if we'll ever see a trailing slash here (pszFilter == NULL), 579 * but if we do we should accept it only for the root. 580 */ 581 else if (pszFilter) 582 { 583 pFilter = pStrFolderPath; 584 pStrFolderPath = vboxSfOs2StrDup(pFilter->String.ach, pszFilter - pFilter->String.ach); 585 if (!pStrFolderPath) 586 rc = ERROR_NOT_ENOUGH_MEMORY; 587 } 588 else if (!pszFilter && pStrFolderPath->u16Length > 1) 589 { 590 LogFlow(("FS32_FINDFIRST: Trailing slash (%s)\n", pStrFolderPath->String.utf8)); 591 rc = ERROR_PATH_NOT_FOUND; 592 } 593 else 594 LogFlow(("FS32_FINDFIRST: Root dir (%s)\n", pStrFolderPath->String.utf8)); 595 596 /* 597 * Make sure we've got a buffer for keeping unused search results. 598 */ 599 PVBOXSFFSBUF pDataBuf = NULL; 600 if (rc == NO_ERROR) 601 { 602 pDataBuf = (PVBOXSFFSBUF)RTMemAlloc(cMaxMatches == 1 ? VBOXSFFSBUF_MIN_SIZE : _16K - ALLOC_HDR_SIZE); 603 if (pDataBuf) 604 pDataBuf->cbBuf = cMaxMatches == 1 ? VBOXSFFSBUF_MIN_SIZE : _16K - ALLOC_HDR_SIZE; 605 else 606 { 607 pDataBuf = (PVBOXSFFSBUF)RTMemAlloc(VBOXSFFSBUF_MIN_SIZE); 608 if (pDataBuf) 609 pDataBuf->cbBuf = VBOXSFFSBUF_MIN_SIZE; 610 else 611 rc = ERROR_NOT_ENOUGH_MEMORY; 612 } 613 } 614 if (rc == NO_ERROR) 615 { 616 /* 617 * Now, try open the directory for reading. 618 * We pre-use the data buffer for parameter passin to avoid 619 * wasting any stack space. 620 */ 621 PSHFLCREATEPARMS pParams = (PSHFLCREATEPARMS)(pDataBuf + 1); 622 RT_ZERO(*pParams); 623 pParams->CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACT_OPEN_IF_EXISTS 624 | SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_ATTR_READ | SHFL_CF_ACCESS_DENYNONE; 625 int vrc = VbglR0SfCreate(&g_SfClient, &pFolder->hHostFolder, pStrFolderPath, pParams); 626 LogFlow(("FS32_FINDFIRST: VbglR0SfCreate(%s) -> %Rrc Result=%d fMode=%#x hHandle=%#RX64\n", 627 pStrFolderPath->String.ach, vrc, pParams->Result, pParams->Info.Attr.fMode, pParams->Handle)); 628 if (RT_SUCCESS(vrc)) 629 { 630 switch (pParams->Result) 631 { 632 case SHFL_FILE_EXISTS: 633 if (pParams->Handle != SHFL_HANDLE_NIL) 634 { 635 /* 636 * Initialize the structures. 637 */ 638 pFsFsd->hHostDir = pParams->Handle; 639 pFsFsd->u32Magic = VBOXSFFS_MAGIC; 640 pFsFsd->pFolder = pFolder; 641 pFsFsd->pBuf = pDataBuf; 642 pFsFsd->offLastFile = 0; 643 pDataBuf->u32Magic = VBOXSFFSBUF_MAGIC; 644 pDataBuf->cbValid = 0; 645 pDataBuf->cEntriesLeft = 0; 646 pDataBuf->pEntry = NULL; 647 pDataBuf->pFilter = pFilter; 648 pDataBuf->fMustHaveAttribs = (uint8_t)((fAttribs >> 8) & (RTFS_DOS_MASK_OS2 >> RTFS_DOS_SHIFT)); 649 pDataBuf->fExcludedAttribs = (uint8_t)(~fAttribs 650 & ( (RTFS_DOS_MASK_OS2 & ~(RTFS_DOS_ARCHIVED | RTFS_DOS_READONLY) 651 >> RTFS_DOS_SHIFT))); 652 pDataBuf->fLongFilenames = RT_BOOL(fAttribs & FF_ATTR_LONG_FILENAME); 653 pDataBuf->cMinLocalTimeDelta = vboxSfOs2GetLocalTimeDelta(); 654 655 rc = vboxSfOs2ReadDirEntries(pFolder, pFsFsd, pDataBuf, uLevel, fFlags, 656 pbData, cbData, cMaxMatches ? cMaxMatches : UINT16_MAX, pcMatches); 657 if (rc == NO_ERROR) 658 { 659 uint32_t cRefs = ASMAtomicIncU32(&pFolder->cOpenSearches); 660 Assert(cRefs < _4K); RT_NOREF(cRefs); 661 662 /* We keep these on success: */ 663 if (pFilter == pStrFolderPath) 664 pStrFolderPath = NULL; 665 pFilter = NULL; 666 pDataBuf = NULL; 667 pFolder = NULL; 668 } 669 else 670 { 671 vrc = VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pFsFsd->hHostDir); 672 AssertRC(vrc); 673 pFsFsd->u32Magic = ~VBOXSFFS_MAGIC; 674 pDataBuf->u32Magic = ~VBOXSFFSBUF_MAGIC; 675 pFsFsd->pFolder = NULL; 676 pFsFsd->hHostDir = NULL; 677 } 678 } 679 else 680 { 681 LogFlow(("FS32_FINDFIRST: VbglR0SfCreate returns NIL handle for '%s'\n", pStrFolderPath->String.utf8)); 682 rc = ERROR_PATH_NOT_FOUND; 683 } 684 break; 685 686 case SHFL_PATH_NOT_FOUND: 687 rc = ERROR_PATH_NOT_FOUND; 688 break; 689 690 default: 691 case SHFL_FILE_NOT_FOUND: 692 rc = ERROR_FILE_NOT_FOUND; 693 break; 694 } 695 } 696 else 697 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_GEN_FAILURE); 698 } 699 700 RTMemFree(pDataBuf); 701 if (pFilter != pStrFolderPath) 702 vboxSfOs2StrFree(pFilter); 703 vboxSfOs2ReleasePathAndFolder(pStrFolderPath, pFolder); 704 } 705 LogFlow(("FS32_FINDFIRST: returns %u\n", rc)); 706 return rc; 707 } 708 709 710 DECLASM(APIRET) 711 FS32_FINDFROMNAME(PFSFSI pFsFsi, PVBOXSFFS pFsFsd, PBYTE pbData, ULONG cbData, PUSHORT pcMatches, 712 ULONG uLevel, ULONG uPosition, PCSZ pszName, ULONG fFlags) 713 { 714 LogFlow(("FS32_FINDFROMNAME: pFsFsi=%p pFsFsd=%p pbData=%p cbData=%#x pcMatches=%p:{%#x} uLevel=%#x uPosition=%#x pszName=%p:{%s} fFlags=%#x\n", 715 pFsFsi, pFsFsd, pbData, cbData, pcMatches, *pcMatches, uLevel, uPosition, pszName, pszName, fFlags)); 716 717 /* 718 * Input validation. 719 */ 720 USHORT const cMaxMatches = *pcMatches; 721 *pcMatches = 0; 722 AssertReturn(pFsFsd->u32Magic == VBOXSFFS_MAGIC, ERROR_SYS_INTERNAL); 723 PVBOXSFFOLDER pFolder = pFsFsd->pFolder; 724 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 725 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 726 Assert(pFolder->cOpenSearches > 0); 727 PVBOXSFFSBUF pDataBuf = pFsFsd->pBuf; 728 AssertReturn(pDataBuf, ERROR_SYS_INTERNAL); 729 Assert(pDataBuf->u32Magic == VBOXSFFSBUF_MAGIC); 730 731 switch (uLevel) 732 { 733 case FI_LVL_STANDARD: 734 case FI_LVL_STANDARD_64: 735 case FI_LVL_STANDARD_EASIZE: 736 case FI_LVL_STANDARD_EASIZE_64: 737 break; 738 739 case FI_LVL_EAS_FROM_LIST: 740 case FI_LVL_EAS_FROM_LIST_64: 741 Log(("FS32_FINDFIRST: FI_LVL_EAS_FROM_LIST[_64] -> ERROR_EAS_NOT_SUPPORTED\n")); 742 return ERROR_EAS_NOT_SUPPORTED; 743 744 default: 745 LogRel(("FS32_FINDFIRST: Unsupported info level %u!\n", uLevel)); 746 return ERROR_INVALID_LEVEL; 747 } 748 749 /* 750 * Check if we're just continuing. This is usually the case. 751 */ 752 APIRET rc; 753 if (uPosition == pFsFsd->offLastFile) 754 rc = vboxSfOs2ReadDirEntries(pFolder, pFsFsd, pDataBuf, uLevel, fFlags, pbData, cbData, 755 cMaxMatches ? cMaxMatches : UINT16_MAX, pcMatches); 756 else 757 { 758 Log(("TODO: uPosition differs: %#x, expected %#x (%s)\n", uPosition, pFsFsd->offLastFile, pszName)); 759 rc = vboxSfOs2ReadDirEntries(pFolder, pFsFsd, pDataBuf, uLevel, fFlags, pbData, cbData, 760 cMaxMatches ? cMaxMatches : UINT16_MAX, pcMatches); 761 } 762 763 RT_NOREF(pFsFsi, pszName); 764 LogFlow(("FS32_FINDFROMNAME: returns %u (*pcMatches=%#x)\n", rc, *pcMatches)); 765 return rc; 766 } 767 768 769 DECLASM(APIRET) 770 FS32_FINDNEXT(PFSFSI pFsFsi, PVBOXSFFS pFsFsd, PBYTE pbData, ULONG cbData, PUSHORT pcMatches, ULONG uLevel, ULONG fFlags) 771 { 772 LogFlow(("FS32_FINDNEXT: pFsFsi=%p pFsFsd=%p pbData=%p cbData=%#x pcMatches=%p:{%#x} uLevel=%#x fFlags=%#x\n", 773 pFsFsi, pFsFsd, pbData, cbData, pcMatches, *pcMatches, uLevel, fFlags)); 774 775 /* 776 * Input validation. 777 */ 778 USHORT const cMaxMatches = *pcMatches; 779 *pcMatches = 0; 780 AssertReturn(pFsFsd->u32Magic == VBOXSFFS_MAGIC, ERROR_SYS_INTERNAL); 781 PVBOXSFFOLDER pFolder = pFsFsd->pFolder; 782 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 783 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 784 Assert(pFolder->cOpenSearches > 0); 785 PVBOXSFFSBUF pDataBuf = pFsFsd->pBuf; 786 AssertReturn(pDataBuf, ERROR_SYS_INTERNAL); 787 Assert(pDataBuf->u32Magic == VBOXSFFSBUF_MAGIC); 788 789 switch (uLevel) 790 { 791 case FI_LVL_STANDARD: 792 case FI_LVL_STANDARD_64: 793 case FI_LVL_STANDARD_EASIZE: 794 case FI_LVL_STANDARD_EASIZE_64: 795 break; 796 797 case FI_LVL_EAS_FROM_LIST: 798 case FI_LVL_EAS_FROM_LIST_64: 799 Log(("FS32_FINDFIRST: FI_LVL_EAS_FROM_LIST[_64] -> ERROR_EAS_NOT_SUPPORTED\n")); 800 return ERROR_EAS_NOT_SUPPORTED; 801 802 default: 803 LogRel(("FS32_FINDFIRST: Unsupported info level %u!\n", uLevel)); 804 return ERROR_INVALID_LEVEL; 805 } 806 807 /* 808 * Read more. 809 */ 810 APIRET rc = vboxSfOs2ReadDirEntries(pFolder, pFsFsd, pDataBuf, uLevel, fFlags, pbData, cbData, 811 cMaxMatches ? cMaxMatches : UINT16_MAX, pcMatches); 812 813 NOREF(pFsFsi); 814 LogFlow(("FS32_FINDNEXT: returns %u (*pcMatches=%#x)\n", rc, *pcMatches)); 815 return rc; 816 } 817 818 819 DECLASM(APIRET) 820 FS32_FINDCLOSE(PFSFSI pFsFsi, PVBOXSFFS pFsFsd) 821 { 822 /* 823 * Input validation. 824 */ 825 AssertReturn(pFsFsd->u32Magic == VBOXSFFS_MAGIC, ERROR_SYS_INTERNAL); 826 PVBOXSFFOLDER pFolder = pFsFsd->pFolder; 827 AssertReturn(pFolder != NULL, ERROR_SYS_INTERNAL); 828 Assert(pFolder->u32Magic == VBOXSFFOLDER_MAGIC); 829 Assert(pFolder->cOpenSearches > 0); 830 PVBOXSFFSBUF pDataBuf = pFsFsd->pBuf; 831 AssertReturn(pDataBuf, ERROR_SYS_INTERNAL); 832 Assert(pDataBuf->u32Magic == VBOXSFFSBUF_MAGIC); 833 834 /* 835 * Close it. 836 */ 837 if (pFsFsd->hHostDir != SHFL_HANDLE_NIL) 838 { 839 int vrc = VbglR0SfClose(&g_SfClient, &pFolder->hHostFolder, pFsFsd->hHostDir); 840 AssertRC(vrc); 841 } 842 843 pFsFsd->u32Magic = ~VBOXSFFS_MAGIC; 844 pFsFsd->hHostDir = SHFL_HANDLE_NIL; 845 pFsFsd->pFolder = NULL; 846 pFsFsd->pBuf = NULL; 847 vboxSfOs2StrFree(pDataBuf->pFilter); 848 pDataBuf->pFilter = NULL; 849 pDataBuf->u32Magic = ~VBOXSFFSBUF_MAGIC; 850 pDataBuf->cbBuf = 0; 851 RTMemFree(pDataBuf); 852 853 uint32_t cRefs = ASMAtomicDecU32(&pFolder->cOpenSearches); 854 Assert(cRefs < _4K); RT_NOREF(cRefs); 855 vboxSfOs2ReleaseFolder(pFolder); 856 857 RT_NOREF(pFsFsi); 858 LogFlow(("FS32_FINDCLOSE: returns NO_ERROR\n")); 859 return NO_ERROR; 860 } 861 862 863 864 865 866 DECLASM(APIRET) 867 FS32_FINDNOTIFYFIRST(PCDFSI pCdFsi, PVBOXSFCD pCdFsd, PCSZ pszPath, LONG offCurDirEnd, ULONG fAttribs, 868 PUSHORT phHandle, PBYTE pbData, ULONG cbData, PUSHORT pcMatches, 869 ULONG uLevel, ULONG fFlags) 870 { 871 RT_NOREF(pCdFsi, pCdFsd, pszPath, offCurDirEnd, fAttribs, phHandle, pbData, cbData, pcMatches, uLevel, fFlags); 49 872 return ERROR_NOT_SUPPORTED; 50 873 } 51 874 52 875 53 DECLASM(int) 54 FS32_FINDFROMNAME(PFSFSI pfsfsi, PVBOXSFFS pfsfsd, PBYTE pbData, USHORT cbData, PUSHORT pcMatch, 55 USHORT uLevel, ULONG position, PCSZ pszName, USHORT fFlags) 56 { 57 NOREF(pfsfsi); NOREF(pfsfsd); NOREF(pbData); NOREF(cbData); NOREF(pcMatch); NOREF(uLevel); NOREF(position); NOREF(pszName); 58 NOREF(fFlags); 876 DECLASM(APIRET) 877 FS32_FINDNOTIFYNEXT(ULONG hHandle, PBYTE pbData, ULONG cbData, PUSHORT pcMatchs, ULONG uLevel, ULONG cMsTimeout) 878 { 879 RT_NOREF(hHandle, pbData, cbData, pcMatchs, uLevel, cMsTimeout); 59 880 return ERROR_NOT_SUPPORTED; 60 881 } 61 882 62 883 63 DECLASM(int) 64 FS32_FINDNEXT(PFSFSI pfsfsi, PVBOXSFFS pfsfsd, PBYTE pbData, USHORT cbData, PUSHORT pcMatch, 65 USHORT uLevel, USHORT fFlags) 66 { 67 NOREF(pfsfsi); NOREF(pfsfsd); NOREF(pbData); NOREF(cbData); NOREF(pcMatch); NOREF(uLevel); NOREF(fFlags); 68 return ERROR_NOT_SUPPORTED; 69 } 70 71 72 DECLASM(int) 73 FS32_FINDCLOSE(PFSFSI pfsfsi, PVBOXSFFS pfsfsd) 74 { 75 NOREF(pfsfsi); NOREF(pfsfsd); 76 return ERROR_NOT_SUPPORTED; 77 } 78 79 80 81 82 83 DECLASM(int) 84 FS32_FINDNOTIFYFIRST(PCDFSI pcdfsi, PVBOXSFCD pcdfsd, PCSZ pszName, USHORT iCurDirEnd, USHORT fAtt, 85 PUSHORT phHandle, PBYTE pbData, USHORT cbData, PUSHORT pcMatch, 86 USHORT uLevel, USHORT fFlags) 87 { 88 NOREF(pcdfsi); NOREF(pcdfsd); NOREF(pszName); NOREF(iCurDirEnd); NOREF(fAtt); NOREF(phHandle); NOREF(pbData); NOREF(cbData); 89 NOREF(pcMatch); NOREF(uLevel); NOREF(fFlags); 90 return ERROR_NOT_SUPPORTED; 91 } 92 93 94 DECLASM(int) 95 FS32_FINDNOTIFYNEXT(USHORT hHandle, PBYTE pbData, USHORT cbData, PUSHORT pcMatch, 96 USHORT uLevel, ULONG cMsTimeout) 97 { 98 NOREF(hHandle); NOREF(pbData); NOREF(cbData); NOREF(pcMatch); NOREF(uLevel); NOREF(cMsTimeout); 99 return ERROR_NOT_SUPPORTED; 100 } 101 102 103 DECLASM(int) 104 FS32_FINDNOTIFYCLOSE(USHORT hHandle) 884 DECLASM(APIRET) 885 FS32_FINDNOTIFYCLOSE(ULONG hHandle) 105 886 { 106 887 NOREF(hHandle); -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFInit.cpp
r68577 r75337 5 5 6 6 /* 7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>7 * Copyright (c) 2007-2018 knut st. osmundsen <[email protected]> 8 8 * 9 9 * Permission is hereby granted, free of charge, to any person … … 37 37 38 38 #include <VBox/VBoxGuestLib.h> 39 #include <VBox/VBoxGuest.h> 39 40 #include <VBox/log.h> 40 41 #include <iprt/assert.h> … … 70 71 DECLASM(void) VBoxSFR0Init(void) 71 72 { 72 Log(("VBoxSFR0Init: g_fpfnDevHlp=%lx u32Version=%RX32 u32Session=%RX32 pfnServiceEP=%p g_u32Info=%u (%#x)\n", 73 g_fpfnDevHlp, g_VBoxGuestIDC.u32Version, g_VBoxGuestIDC.u32Session, g_VBoxGuestIDC.pfnServiceEP, g_u32Info, g_u32Info)); 73 RTLogBackdoorPrintf("VBoxSFR0Init: g_fpfnDevHlp=%lx u32Version=%RX32 u32Session=%RX32 pfnServiceEP=%p g_u32Info=%u (%#x)\n", 74 g_fpfnDevHlp, g_VBoxGuestIDC.u32Version, g_VBoxGuestIDC.u32Session, g_VBoxGuestIDC.pfnServiceEP, g_u32Info, g_u32Info); 75 RTLogBackdoorPrintf("&KernSISData=%p\n", &KernSISData); 76 RTLogBackdoorPrintf("&KernLISData=%p\n", &KernLISData); 77 RTLogBackdoorPrintf("KernInterruptLevel=%#x\n", KernInterruptLevel); 78 RTLogBackdoorPrintf("KernTKSSBase=%p\n", KernTKSSBase); 79 80 KernAllocMutexLock(&g_MtxFolders); 81 RTListInit(&g_FolderHead); 74 82 75 83 /* … … 101 109 #endif 102 110 103 Log(("VBoxSFR0Init: completed successfully\n"));111 RTLogBackdoorPrintf("VBoxSFR0Init: completed successfully\n"); 104 112 return; 105 113 } 106 114 } 107 115 108 LogRel(("VBoxSF: RTR0Init failed, rc=%Rrc\n", rc));116 RTLogBackdoorPrintf("VBoxSF: RTR0Init failed, rc=%Rrc\n", rc); 109 117 } 110 118 else 111 LogRel(("VBoxSF: Failed to connect to VBoxGuest.sys.\n"));119 RTLogBackdoorPrintf("VBoxSF: Failed to connect to VBoxGuest.sys.\n"); 112 120 } 113 121 -
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFInternal.h
r69474 r75337 36 36 #define INCL_ERROR 37 37 #define INCL_LONGLONG 38 # include <os2.h>38 #define OS2EMX_PLAIN_CHAR 39 39 #include <os2ddk/bsekee.h> 40 40 #include <os2ddk/devhlp.h> … … 45 45 #include <iprt/types.h> 46 46 #include <iprt/assert.h> 47 #include <iprt/list.h> 48 #include <VBox/VBoxGuestLibSharedFolders.h> 49 50 51 /** Allocation header used by RTMemAlloc. 52 * This should be subtracted from round numbers. */ 53 #define ALLOC_HDR_SIZE (0x10 + 4) 54 55 56 /** 57 * A shared folder 58 */ 59 typedef struct VBOXSFFOLDER 60 { 61 /** For the shared folder list. */ 62 RTLISTNODE ListEntry; 63 /** Magic number (VBOXSFFOLDER_MAGIC). */ 64 uint32_t u32Magic; 65 /** Number of active references to this folder. */ 66 uint32_t volatile cRefs; 67 /** Number of open files referencing this folder. */ 68 uint32_t volatile cOpenFiles; 69 /** Number of open searches referencing this folder. */ 70 uint32_t volatile cOpenSearches; 71 /** Number of drives this is attached to. */ 72 uint8_t volatile cDrives; 73 74 /** The host folder handle. */ 75 VBGLSFMAP hHostFolder; 76 77 /** OS/2 volume handle. */ 78 USHORT hVpb; 79 80 /** The length of the folder name. */ 81 uint8_t cchName; 82 /** The shared folder name. */ 83 char szName[RT_FLEXIBLE_ARRAY]; 84 } VBOXSFFOLDER; 85 /** Pointer to a shared folder. */ 86 typedef VBOXSFFOLDER *PVBOXSFFOLDER; 87 /** Magic value for VBOXSFVP (Neal Town Stephenson). */ 88 #define VBOXSFFOLDER_MAGIC UINT32_C(0x19591031) 89 90 /** The shared mutex protecting folders list, drives and the connection. */ 91 extern MutexLock_t g_MtxFolders; 92 /** List of active folder (PVBOXSFFOLDER). */ 93 extern RTLISTANCHOR g_FolderHead; 47 94 48 95 … … 50 97 * VBoxSF Volume Parameter Structure. 51 98 * 52 * @remark Overlays the 36 byte VPFSD structure (fsd.h). 99 * @remarks Overlays the 36 byte VPFSD structure (fsd.h). 100 * @note No self pointer as the kernel may reallocate these. 53 101 */ 54 102 typedef struct VBOXSFVP 55 103 { 56 uint32_t u32Dummy; 104 /** Magic value (VBOXSFVP_MAGIC). */ 105 uint32_t u32Magic; 106 /** The folder. */ 107 PVBOXSFFOLDER pFolder; 57 108 } VBOXSFVP; 58 109 AssertCompile(sizeof(VBOXSFVP) <= sizeof(VPFSD)); 59 110 /** Pointer to a VBOXSFVP struct. */ 60 111 typedef VBOXSFVP *PVBOXSFVP; 112 /** Magic value for VBOXSFVP (Laurence van Cott Niven). */ 113 #define VBOXSFVP_MAGIC UINT32_C(0x19380430) 61 114 62 115 … … 80 133 * @remark Overlays the 30 byte SFFSD structure (fsd.h). 81 134 */ 82 typedef struct VBOXSFFSD 83 { 135 typedef struct VBOXSFSYFI 136 { 137 /** Magic value (VBOXSFSYFI_MAGIC). */ 138 uint32_t u32Magic; 84 139 /** Self pointer for quick 16:16 to flat translation. */ 85 struct VBOXSFFSD *pSelf; 86 } VBOXSFFSD; 87 AssertCompile(sizeof(VBOXSFFSD) <= sizeof(SFFSD)); 88 /** Pointer to a VBOXSFFSD struct. */ 89 typedef VBOXSFFSD *PVBOXSFFSD; 140 struct VBOXSFSYFI *pSelf; 141 /** The host file handle. */ 142 SHFLHANDLE hHostFile; 143 /** The shared folder (referenced). */ 144 PVBOXSFFOLDER pFolder; 145 } VBOXSFSYFI; 146 AssertCompile(sizeof(VBOXSFSYFI) <= sizeof(SFFSD)); 147 /** Pointer to a VBOXSFSYFI struct. */ 148 typedef VBOXSFSYFI *PVBOXSFSYFI; 149 /** Magic value for VBOXSFSYFI (Jon Ellis Meacham). */ 150 #define VBOXSFSYFI_MAGIC UINT32_C(0x19690520) 151 152 153 /** 154 * VBoxSF File Search Buffer (header). 155 */ 156 typedef struct VBOXSFFSBUF 157 { 158 /** A magic number (VBOXSFFSBUF_MAGIC). */ 159 uint32_t u32Magic; 160 /** Amount of buffer space allocated after this header. */ 161 uint32_t cbBuf; 162 /** The filter string (full path), NULL if all files are request. */ 163 PSHFLSTRING pFilter; 164 /** Must have attributes (shifted down DOS attributes). */ 165 uint8_t fMustHaveAttribs; 166 /** Non-matching attributes (shifted down DOS attributes). */ 167 uint8_t fExcludedAttribs; 168 /** Set if FF_ATTR_LONG_FILENAME. */ 169 bool fLongFilenames : 1; 170 uint8_t bPadding1; 171 /** The local time offset to use for this search. */ 172 int16_t cMinLocalTimeDelta; 173 uint8_t abPadding2[2]; 174 /** Number of valid bytes in the buffer. */ 175 uint32_t cbValid; 176 /** Number of entries left in the buffer. */ 177 uint32_t cEntriesLeft; 178 /** The next entry. */ 179 PSHFLDIRINFO pEntry; 180 /** Staging area for staging a full FILEFINDBUF4L (+ 32 safe bytes). */ 181 uint8_t abStaging[RT_ALIGN_32(sizeof(FILEFINDBUF4L) + 32, 8)]; 182 /** For temporary convertion to UTF-8 so we can use KernStrFromUcs to get 183 * string encoded according to the process codepage. */ 184 RTUTF16 wszTmp[260]; 185 } VBOXSFFSBUF; 186 AssertCompileSizeAlignment(VBOXSFFSBUF, 8); 187 /** Pointer to a file search buffer. */ 188 typedef VBOXSFFSBUF *PVBOXSFFSBUF; 189 /** Magic number for VBOXSFFSBUF (Robert Anson Heinlein). */ 190 #define VBOXSFFSBUF_MAGIC UINT32_C(0x19070707) 191 /** Minimum buffer size. */ 192 #define VBOXSFFSBUF_MIN_SIZE ( RT_ALIGN_32(sizeof(VBOXSFFSBUF) + sizeof(SHFLDIRINFO) + CCHMAXPATHCOMP * 4 + ALLOC_HDR_SIZE, 64) \ 193 - ALLOC_HDR_SIZE) 90 194 91 195 … … 94 198 * 95 199 * @remark Overlays the 24 byte FSFSD structure (fsd.h). 200 * @note No self pointer as the kernel may reallocate these. 96 201 */ 97 202 typedef struct VBOXSFFS 98 203 { 99 /** Self pointer for quick 16:16 to flat translation. */ 100 struct VBOXSFFS *pSelf; 204 /** Magic value (VBOXSFFS_MAGIC). */ 205 uint32_t u32Magic; 206 /** The last file position position. */ 207 uint32_t offLastFile; 208 /** The host directory handle. */ 209 SHFLHANDLE hHostDir; 210 /** The shared folder (referenced). */ 211 PVBOXSFFOLDER pFolder; 212 /** Search data buffer. */ 213 PVBOXSFFSBUF pBuf; 101 214 } VBOXSFFS; 102 215 AssertCompile(sizeof(VBOXSFFS) <= sizeof(FSFSD)); 103 216 /** Pointer to a VBOXSFFS struct. */ 104 217 typedef VBOXSFFS *PVBOXSFFS; 105 218 /** Magic number for VBOXSFFS (Isaak Azimov). */ 219 #define VBOXSFFS_MAGIC UINT32_C(0x19200102) 220 221 222 extern VBGLSFCLIENT g_SfClient; 223 224 PSHFLSTRING vboxSfOs2StrAlloc(size_t cchLength); 225 PSHFLSTRING vboxSfOs2StrDup(const char *pachSrc, size_t cchSrc); 226 void vboxSfOs2StrFree(PSHFLSTRING pStr); 227 228 APIRET vboxSfOs2ResolvePath(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd, 229 PVBOXSFFOLDER *ppFolder, PSHFLSTRING *ppStrFolderPath); 230 void vboxSfOs2ReleasePathAndFolder(PSHFLSTRING pStrPath, PVBOXSFFOLDER pFolder); 231 void vboxSfOs2ReleaseFolder(PVBOXSFFOLDER pFolder); 232 APIRET vboxSfOs2ConvertStatusToOs2(int vrc, APIRET rcDefault); 233 int16_t vboxSfOs2GetLocalTimeDelta(void); 234 void vboxSfOs2DateTimeFromTimeSpec(FDATE *pDosDate, FTIME *pDosTime, RTTIMESPEC SrcTimeSpec, int16_t cMinLocalTimeDelta); 235 PRTTIMESPEC vboxSfOs2DateTimeToTimeSpec(FDATE DosDate, FTIME DosTime, int16_t cMinLocalTimeDelta, PRTTIMESPEC pDstTimeSpec); 236 APIRET vboxSfOs2FileStatusFromObjInfo(PBYTE pbDst, ULONG cbDst, ULONG uLevel, SHFLFSOBJINFO const *pSrc); 237 APIRET vboxSfOs2SetInfoCommonWorker(PVBOXSFFOLDER pFolder, SHFLHANDLE hHostFile, ULONG fAttribs, 238 PFILESTATUS pTimestamps, PSHFLFSOBJINFO pObjInfoBuf); 239 APIRET vboxSfOs2MakeEmptyEaList(PEAOP pEaOp, ULONG uLevel); 240 APIRET vboxSfOs2MakeEmptyEaListEx(PEAOP pEaOp, ULONG uLevel, uint32_t *pcbWritten, ULONG *poffError); 241 242 DECLASM(PVBOXSFVP) Fsh32GetVolParams(USHORT hVbp, PVPFSI *ppVpFsi /*optional*/); 106 243 107 244 #endif
Note:
See TracChangeset
for help on using the changeset viewer.