Changeset 78326 in vbox for trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsfhlp.cpp
- Timestamp:
- Apr 26, 2019 2:45:38 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsfhlp.cpp
r78321 r78326 28 28 *********************************************************************************************************************************/ 29 29 #ifdef DEBUG 30 static int s_iAllocRefCount= 0;30 static int volatile g_cAllocations = 0; 31 31 #endif 32 32 33 34 NTSTATUS vbsfHlpCreateDriveLetter(WCHAR Letter, UNICODE_STRING *pDeviceName)35 {36 UNICODE_STRING driveName;37 RtlInitUnicodeString(&driveName,L"\\??\\_:" );38 39 /* Replace '_' with actual drive letter */40 driveName.Buffer[driveName.Length/sizeof(WCHAR) - 2] = Letter;41 42 return IoCreateSymbolicLink(&driveName, pDeviceName);43 }44 45 NTSTATUS vbsfHlpDeleteDriveLetter(WCHAR Letter)46 {47 UNICODE_STRING driveName;48 RtlInitUnicodeString(&driveName,L"\\??\\_:" );49 50 /* Replace '_' with actual drive letter */51 driveName.Buffer[driveName.Length/sizeof(WCHAR) - 2] = Letter;52 53 return IoDeleteSymbolicLink(&driveName);54 }55 33 56 34 /** … … 61 39 * 62 40 */ 63 NTSTATUS VBoxErrorToNTStatus(int vrc)41 NTSTATUS vbsfNtVBoxStatusToNt(int vrc) 64 42 { 65 43 NTSTATUS Status; … … 147 125 148 126 default: 149 /** @todo error handling */150 127 Status = STATUS_INVALID_PARAMETER; 151 128 Log(("Unexpected vbox error %Rrc\n", … … 156 133 } 157 134 158 PVOID vbsfAllocNonPagedMem(ULONG ulSize) 159 { 160 PVOID pMemory = NULL; 161 135 /** 136 * Wrapper around ExAllocatePoolWithTag. 137 */ 138 PVOID vbsfNtAllocNonPagedMem(ULONG cbMemory) 139 { 140 /* Tag is reversed (a.k.a "SHFL") to display correctly in debuggers, so search for "SHFL" */ 141 PVOID pMemory = ExAllocatePoolWithTag(NonPagedPool, cbMemory, 'LFHS'); 142 if (NULL != pMemory) 143 { 144 RtlZeroMemory(pMemory, cbMemory); 162 145 #ifdef DEBUG 163 s_iAllocRefCount = s_iAllocRefCount +1;164 Log(("vbsfAllocNonPagedMem: RefCnt after incrementing: %d\n", s_iAllocRefCount));146 int const cAllocations = g_cAllocations += 1; 147 Log(("vbsfNtAllocNonPagedMem: Allocated %u bytes of memory at %p (g_iAllocRefCount=%d)\n", cbMemory, pMemory, cAllocations)); 165 148 #endif 166 167 /* Tag is reversed (a.k.a "SHFL") to display correctly in debuggers, so search for "SHFL" */ 168 pMemory = ExAllocatePoolWithTag(NonPagedPool, ulSize, 'LFHS'); 169 170 if (NULL != pMemory) 171 { 172 RtlZeroMemory(pMemory, ulSize); 149 } 173 150 #ifdef DEBUG 174 Log(("vbsfAllocNonPagedMem: Allocated %d bytes of memory at %p.\n", ulSize, pMemory)); 151 else 152 Log(("vbsfNtAllocNonPagedMem: ERROR: Could not allocate %u bytes of memory!\n", cbMemory)); 175 153 #endif 154 return pMemory; 155 } 156 157 /** 158 * Wrapper around ExFreePoolWithTag. 159 */ 160 void vbsfNtFreeNonPagedMem(PVOID pvMemory) 161 { 162 #ifdef DEBUG 163 int cAllocations = g_cAllocations -= 1; 164 Log(("vbsfNtFreeNonPagedMem: %p (g_cAllocations=%d)\n", pvMemory, cAllocations)); 165 #endif 166 AssertPtr(pvMemory); 167 168 /* Tagged allocations must be freed using the same tag as used when allocating the memory. */ 169 ExFreePoolWithTag(pvMemory, 'LFHS'); 170 } 171 172 /** Allocate and initialize a SHFLSTRING from a UNICODE string. 173 * 174 * @param ppShflString Where to store the pointer to the allocated SHFLSTRING structure. 175 * The structure must be deallocated with vbsfNtFreeNonPagedMem. 176 * @param pwc The UNICODE string. If NULL then SHFL is only allocated. 177 * @param cb Size of the UNICODE string in bytes without the trailing nul. 178 * 179 * @return Status code. 180 */ 181 NTSTATUS vbsfNtShflStringFromUnicodeAlloc(PSHFLSTRING *ppShflString, const WCHAR *pwc, uint16_t cb) 182 { 183 NTSTATUS Status; 184 185 /* Calculate length required for the SHFL structure: header + chars + nul. */ 186 ULONG const cbShflString = SHFLSTRING_HEADER_SIZE + cb + sizeof(WCHAR); 187 PSHFLSTRING pShflString = (PSHFLSTRING)vbsfNtAllocNonPagedMem(cbShflString); 188 if (pShflString) 189 { 190 if (ShflStringInitBuffer(pShflString, cbShflString)) 191 { 192 if (pwc) 193 { 194 RtlCopyMemory(pShflString->String.ucs2, pwc, cb); 195 pShflString->String.ucs2[cb / sizeof(WCHAR)] = 0; 196 pShflString->u16Length = cb; /* without terminating null */ 197 AssertMsg(pShflString->u16Length + sizeof(WCHAR) == pShflString->u16Size, 198 ("u16Length %d, u16Size %d\n", pShflString->u16Length, pShflString->u16Size)); 199 } 200 else 201 { 202 /** @todo r=bird: vbsfNtAllocNonPagedMem already zero'ed it... */ 203 RtlZeroMemory(pShflString->String.ucs2, cb + sizeof(WCHAR)); 204 pShflString->u16Length = 0; /* without terminating null */ 205 AssertMsg(pShflString->u16Size >= sizeof(WCHAR), 206 ("u16Size %d\n", pShflString->u16Size)); 207 } 208 209 *ppShflString = pShflString; 210 Status = STATUS_SUCCESS; 211 } 212 else 213 { 214 vbsfNtFreeNonPagedMem(pShflString); 215 Status = STATUS_INSUFFICIENT_RESOURCES; 216 } 176 217 } 177 218 else 178 { 179 #ifdef DEBUG 180 Log(("vbsfAllocNonPagedMem: ERROR: Could not allocate %d bytes of memory!\n", ulSize)); 181 #endif 182 } 183 184 return pMemory; 185 } 186 187 void vbsfFreeNonPagedMem(PVOID lpMem) 188 { 189 #ifdef DEBUG 190 s_iAllocRefCount = s_iAllocRefCount - 1; 191 Log(("vbsfFreeNonPagedMem: RefCnt after decrementing: %d\n", s_iAllocRefCount)); 192 #endif 193 194 Assert(lpMem); 195 196 /* MSDN: The ExFreePoolWithTag routine issues a bug check if the specified value for Tag does not match the tag value passed 197 to the routine that originally allocated the memory block. Otherwise, the behavior of this routine is identical to ExFreePool. */ 198 ExFreePoolWithTag(lpMem, 'LFHS'); 199 lpMem = NULL; 200 } 201 202 #if 0 //def DEBUG 203 /** 204 * Callback for RTLogFormatV which writes to the backdoor. 205 * See PFNLOGOUTPUT() for details. 206 */ 207 static DECLCALLBACK(size_t) rtLogBackdoorOutput(void *pv, const char *pachChars, size_t cbChars) 208 { 209 RTLogWriteUser(pachChars, cbChars); 210 return cbChars; 211 } 212 213 int RTLogBackdoorPrintf1(const char *pszFormat, ...) 214 { 215 va_list args; 216 217 LARGE_INTEGER time; 218 219 KeQueryTickCount(&time); 220 221 RTLogBackdoorPrintf("T=%RX64 ", time.QuadPart); 222 va_start(args, pszFormat); 223 RTLogFormatV(rtLogBackdoorOutput, NULL, pszFormat, args); 224 va_end(args); 225 226 return 0; 227 } 228 #endif 219 Status = STATUS_INSUFFICIENT_RESOURCES; 220 221 return Status; 222 } 229 223 230 224 #if defined(DEBUG) || defined(LOG_ENABLED) 231 225 232 static PCHAR PnPMinorFunctionString(LONG MinorFunction) 226 /** Debug routine for translating a minor PNP function to a string. */ 227 static const char *vbsfNtMinorPnpFunctionName(LONG MinorFunction) 233 228 { 234 229 switch (MinorFunction) … … 285 280 } 286 281 287 PCHAR MajorFunctionString(UCHAR MajorFunction, LONG MinorFunction) 282 /** Debug routine for translating a major+minor IPR function to a string. */ 283 const char *vbsfNtMajorFunctionName(UCHAR MajorFunction, LONG MinorFunction) 288 284 { 289 285 switch (MajorFunction) 290 286 { 291 case IRP_MJ_CREATE: 292 return "IRP_MJ_CREATE"; 293 case IRP_MJ_CREATE_NAMED_PIPE: 294 return "IRP_MJ_CREATE_NAMED_PIPE"; 295 case IRP_MJ_CLOSE: 296 return "IRP_MJ_CLOSE"; 297 case IRP_MJ_READ: 298 return "IRP_MJ_READ"; 299 case IRP_MJ_WRITE: 300 return "IRP_MJ_WRITE"; 301 case IRP_MJ_QUERY_INFORMATION: 302 return "IRP_MJ_QUERY_INFORMATION"; 303 case IRP_MJ_SET_INFORMATION: 304 return "IRP_MJ_SET_INFORMATION"; 305 case IRP_MJ_QUERY_EA: 306 return "IRP_MJ_QUERY_EA"; 307 case IRP_MJ_SET_EA: 308 return "IRP_MJ_SET_EA"; 309 case IRP_MJ_FLUSH_BUFFERS: 310 return "IRP_MJ_FLUSH_BUFFERS"; 311 case IRP_MJ_QUERY_VOLUME_INFORMATION: 312 return "IRP_MJ_QUERY_VOLUME_INFORMATION"; 313 case IRP_MJ_SET_VOLUME_INFORMATION: 314 return "IRP_MJ_SET_VOLUME_INFORMATION"; 315 case IRP_MJ_DIRECTORY_CONTROL: 316 return "IRP_MJ_DIRECTORY_CONTROL"; 317 case IRP_MJ_FILE_SYSTEM_CONTROL: 318 return "IRP_MJ_FILE_SYSTEM_CONTROL"; 319 case IRP_MJ_DEVICE_CONTROL: 320 return "IRP_MJ_DEVICE_CONTROL"; 321 case IRP_MJ_INTERNAL_DEVICE_CONTROL: 322 return "IRP_MJ_INTERNAL_DEVICE_CONTROL"; 323 case IRP_MJ_SHUTDOWN: 324 return "IRP_MJ_SHUTDOWN"; 325 case IRP_MJ_LOCK_CONTROL: 326 return "IRP_MJ_LOCK_CONTROL"; 327 case IRP_MJ_CLEANUP: 328 return "IRP_MJ_CLEANUP"; 329 case IRP_MJ_CREATE_MAILSLOT: 330 return "IRP_MJ_CREATE_MAILSLOT"; 331 case IRP_MJ_QUERY_SECURITY: 332 return "IRP_MJ_QUERY_SECURITY"; 333 case IRP_MJ_SET_SECURITY: 334 return "IRP_MJ_SET_SECURITY"; 335 case IRP_MJ_POWER: 336 return "IRP_MJ_POWER"; 337 case IRP_MJ_SYSTEM_CONTROL: 338 return "IRP_MJ_SYSTEM_CONTROL"; 339 case IRP_MJ_DEVICE_CHANGE: 340 return "IRP_MJ_DEVICE_CHANGE"; 341 case IRP_MJ_QUERY_QUOTA: 342 return "IRP_MJ_QUERY_QUOTA"; 343 case IRP_MJ_SET_QUOTA: 344 return "IRP_MJ_SET_QUOTA"; 287 RT_CASE_RET_STR(IRP_MJ_CREATE); 288 RT_CASE_RET_STR(IRP_MJ_CREATE_NAMED_PIPE); 289 RT_CASE_RET_STR(IRP_MJ_CLOSE); 290 RT_CASE_RET_STR(IRP_MJ_READ); 291 RT_CASE_RET_STR(IRP_MJ_WRITE); 292 RT_CASE_RET_STR(IRP_MJ_QUERY_INFORMATION); 293 RT_CASE_RET_STR(IRP_MJ_SET_INFORMATION); 294 RT_CASE_RET_STR(IRP_MJ_QUERY_EA); 295 RT_CASE_RET_STR(IRP_MJ_SET_EA); 296 RT_CASE_RET_STR(IRP_MJ_FLUSH_BUFFERS); 297 RT_CASE_RET_STR(IRP_MJ_QUERY_VOLUME_INFORMATION); 298 RT_CASE_RET_STR(IRP_MJ_SET_VOLUME_INFORMATION); 299 RT_CASE_RET_STR(IRP_MJ_DIRECTORY_CONTROL); 300 RT_CASE_RET_STR(IRP_MJ_FILE_SYSTEM_CONTROL); 301 RT_CASE_RET_STR(IRP_MJ_DEVICE_CONTROL); 302 RT_CASE_RET_STR(IRP_MJ_INTERNAL_DEVICE_CONTROL); 303 RT_CASE_RET_STR(IRP_MJ_SHUTDOWN); 304 RT_CASE_RET_STR(IRP_MJ_LOCK_CONTROL); 305 RT_CASE_RET_STR(IRP_MJ_CLEANUP); 306 RT_CASE_RET_STR(IRP_MJ_CREATE_MAILSLOT); 307 RT_CASE_RET_STR(IRP_MJ_QUERY_SECURITY); 308 RT_CASE_RET_STR(IRP_MJ_SET_SECURITY); 309 RT_CASE_RET_STR(IRP_MJ_POWER); 310 RT_CASE_RET_STR(IRP_MJ_SYSTEM_CONTROL); 311 RT_CASE_RET_STR(IRP_MJ_DEVICE_CHANGE); 312 RT_CASE_RET_STR(IRP_MJ_QUERY_QUOTA); 313 RT_CASE_RET_STR(IRP_MJ_SET_QUOTA); 345 314 case IRP_MJ_PNP: 346 return PnPMinorFunctionString(MinorFunction); 347 315 return vbsfNtMinorPnpFunctionName(MinorFunction); 348 316 default: 349 return " unknown_pnp_irp";317 return "IRP_MJ_UNKNOWN"; 350 318 } 351 319 } … … 353 321 #endif /* DEBUG || LOG_ENABLED */ 354 322 355 /** Allocate and initialize a SHFLSTRING from a UNICODE string.356 *357 * @param ppShflString Where to store the pointer to the allocated SHFLSTRING structure.358 * The structure must be deallocated with vbsfFreeNonPagedMem.359 * @param pwc The UNICODE string. If NULL then SHFL is only allocated.360 * @param cb Size of the UNICODE string in bytes without the trailing nul.361 *362 * @return Status code.363 */364 NTSTATUS vbsfShflStringFromUnicodeAlloc(PSHFLSTRING *ppShflString, const WCHAR *pwc, uint16_t cb)365 {366 NTSTATUS Status = STATUS_SUCCESS;367 368 PSHFLSTRING pShflString;369 ULONG cbShflString;370 371 /* Calculate length required for the SHFL structure: header + chars + nul. */372 cbShflString = SHFLSTRING_HEADER_SIZE + cb + sizeof(WCHAR);373 pShflString = (PSHFLSTRING)vbsfAllocNonPagedMem(cbShflString);374 if (pShflString)375 {376 if (ShflStringInitBuffer(pShflString, cbShflString))377 {378 if (pwc)379 {380 RtlCopyMemory(pShflString->String.ucs2, pwc, cb);381 pShflString->String.ucs2[cb / sizeof(WCHAR)] = 0;382 pShflString->u16Length = cb; /* without terminating null */383 AssertMsg(pShflString->u16Length + sizeof(WCHAR) == pShflString->u16Size,384 ("u16Length %d, u16Size %d\n", pShflString->u16Length, pShflString->u16Size));385 }386 else387 {388 /** @todo r=bird: vbsfAllocNonPagedMem already zero'ed it... */389 RtlZeroMemory(pShflString->String.ucs2, cb + sizeof(WCHAR));390 pShflString->u16Length = 0; /* without terminating null */391 AssertMsg(pShflString->u16Size >= sizeof(WCHAR),392 ("u16Size %d\n", pShflString->u16Size));393 }394 395 *ppShflString = pShflString;396 }397 else398 {399 vbsfFreeNonPagedMem(pShflString);400 Status = STATUS_INSUFFICIENT_RESOURCES;401 }402 }403 else404 {405 Status = STATUS_INSUFFICIENT_RESOURCES;406 }407 408 return Status;409 }
Note:
See TracChangeset
for help on using the changeset viewer.