Changeset 95083 in vbox
- Timestamp:
- May 24, 2022 8:46:07 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/pipe-win.cpp
r93115 r95083 38 38 #include <iprt/critsect.h> 39 39 #include <iprt/err.h> 40 #include <iprt/log.h> 40 41 #include <iprt/mem.h> 41 42 #include <iprt/string.h> … … 1203 1204 return rc; 1204 1205 1206 /** @todo The file size should give the same info and be slightly faster... */ 1205 1207 DWORD cbAvailable = 0; 1206 1208 if (PeekNamedPipe(pThis->hPipe, NULL, 0, NULL, &cbAvailable, NULL)) 1209 { 1210 #if ARCH_BITS == 32 1211 /* 1212 * Kludge! 1213 * 1214 * Prior to XP SP1 (?), the returned cbAvailable value was not adjusted 1215 * by read position in the current message/buffer, so it could 1216 * potentially be too high. This could cause the caller to try read 1217 * more data than what's actually available, which may cause the read 1218 * to block when the caller thought it wouldn't. 1219 * 1220 * To get the accurate size, we have to provide and output buffer 1221 * and see how much we actually get back in it, as the data peeking 1222 * works correctly (as you would expect). 1223 */ 1224 if (cbAvailable == 0 || g_enmWinVer >= kRTWinOSType_XP64) 1225 { /* No data available or kernel shouldn't be affected. */ } 1226 else 1227 { 1228 for (unsigned i = 0; ; i++) 1229 { 1230 uint8_t abBufStack[_16K]; 1231 void *pvBufFree = NULL; 1232 void *pvBuf; 1233 DWORD cbBuf = RT_ALIGN_32(cbAvailable + i * 256, 64); 1234 if (cbBuf <= sizeof(abBufStack)) 1235 { 1236 pvBuf = abBufStack; 1237 /* No cbBuf = sizeof(abBufStack) here! PeekNamedPipe bounce buffers the request on the heap. */ 1238 } 1239 else 1240 { 1241 pvBufFree = pvBuf = RTMemTmpAlloc(cbBuf); 1242 if (!pvBuf) 1243 { 1244 rc = VERR_NO_TMP_MEMORY; 1245 cbAvailable = 1; 1246 break; 1247 } 1248 } 1249 1250 DWORD cbAvailable2 = 0; 1251 DWORD cbRead = 0; 1252 BOOL fRc = PeekNamedPipe(pThis->hPipe, pvBuf, cbBuf, &cbRead, &cbAvailable2, NULL); 1253 Log(("RTPipeQueryReadable: #%u: cbAvailable=%#x cbRead=%#x cbAvailable2=%#x (cbBuf=%#x)\n", 1254 i, cbAvailable, cbRead, cbAvailable2, cbBuf)); 1255 1256 RTMemTmpFree(pvBufFree); 1257 1258 if (fRc) 1259 { 1260 if (cbAvailable2 <= cbBuf || i >= 10) 1261 cbAvailable = cbRead; 1262 else 1263 { 1264 cbAvailable = cbAvailable2; 1265 continue; 1266 } 1267 } 1268 else 1269 { 1270 rc = RTErrConvertFromWin32(GetLastError()); 1271 cbAvailable = 1; 1272 } 1273 break; 1274 } 1275 } 1276 #endif 1207 1277 *pcbReadable = cbAvailable; 1278 } 1208 1279 else 1209 1280 rc = RTErrConvertFromWin32(GetLastError());
Note:
See TracChangeset
for help on using the changeset viewer.