Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

728 lines
19 KiB

  1. //
  2. // OSI.C
  3. // Operating System Independent DLL
  4. // * Graphical Output tracking (DDI hook/display driver)
  5. // * Window/Task tracking (Window hook)
  6. //
  7. // Copyright(c) Microsoft 1997-
  8. //
  9. #include <as16.h>
  10. #include <version.h>
  11. #include <ndcgver.h>
  12. PALETTEENTRY CODESEG g_osiVgaPalette[16] =
  13. {
  14. {0x00, 0x00, 0x00, 0x00}, // Black 0x00
  15. {0x80, 0x00, 0x00, 0x00}, // Dk Red 0x01
  16. {0x00, 0x80, 0x00, 0x00}, // Dk Green 0x02
  17. {0x80, 0x80, 0x00, 0x00}, // Dk Yellow 0x03
  18. {0x00, 0x00, 0x80, 0x00}, // Dk Blue 0x04
  19. {0x80, 0x00, 0x80, 0x00}, // Dk Purple 0x05
  20. {0x00, 0x80, 0x80, 0x00}, // Dk Teal 0x06
  21. {0xC0, 0xC0, 0xC0, 0x00}, // Gray 0x07
  22. {0x80, 0x80, 0x80, 0x00}, // Dk Gray 0x08 or 0xF8
  23. {0xFF, 0x00, 0x00, 0x00}, // Red 0x09 or 0xF9
  24. {0x00, 0xFF, 0x00, 0x00}, // Green 0x0A or 0xFA
  25. {0xFF, 0xFF, 0x00, 0x00}, // Yellow 0x0B or 0xFB
  26. {0x00, 0x00, 0xFF, 0x00}, // Blue 0x0C or 0xFC
  27. {0xFF, 0x00, 0xFF, 0x00}, // Purple 0x0D or 0xFD
  28. {0x00, 0xFF, 0xFF, 0x00}, // Teal 0x0E or 0xFE
  29. {0xFF, 0xFF, 0xFF, 0x00} // White 0x0F or 0xFF
  30. };
  31. // --------------------------------------------------------------------------
  32. //
  33. // DllEntryPoint
  34. //
  35. // --------------------------------------------------------------------------
  36. BOOL WINAPI DllEntryPoint(DWORD dwReason, WORD hInst, WORD wDS,
  37. WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
  38. {
  39. switch (dwReason)
  40. {
  41. case DLL_PROCESS_ATTACH:
  42. // First app pulled us in
  43. if (g_cProcesses++ == 0)
  44. {
  45. g_hInstAs16 = (HINSTANCE)hInst;
  46. }
  47. break;
  48. case DLL_PROCESS_DETACH:
  49. // Last app went away
  50. if (--g_cProcesses == 0)
  51. {
  52. // Clean up anything that got left around
  53. OSITerm16(TRUE);
  54. }
  55. break;
  56. }
  57. return(TRUE);
  58. }
  59. //
  60. // OSILoad16
  61. // Called on process attach of mnmcpi32.dll, to establish the flat thunks
  62. // and return back our instance handle
  63. //
  64. void WINAPI OSILoad16
  65. (
  66. LPDWORD lpdwInstance
  67. )
  68. {
  69. DebugEntry(OSI_Load16);
  70. *lpdwInstance = (DWORD)(UINT)g_hInstAs16;
  71. DebugExitVOID(OSI_Load16);
  72. }
  73. // --------------------------------------------------------------------------
  74. //
  75. // OSIInit16
  76. //
  77. // Inits binary patcher, gdi + user patching, windows hooks, etc.
  78. //
  79. // --------------------------------------------------------------------------
  80. BOOL WINAPI OSIInit16
  81. (
  82. DWORD version,
  83. HWND hwndCore,
  84. LPDWORD ppSharedMem,
  85. LPDWORD ppoaSharedMem,
  86. LPDWORD ppimSharedMem,
  87. LPDWORD lpsbcEnabled,
  88. LPDWORD ppShuntBuffers,
  89. LPDWORD pBitmasks
  90. )
  91. {
  92. BOOL rc = FALSE;
  93. HGLOBAL hMem;
  94. HMODULE hModDisplay;
  95. DebugEntry(OSIInit16);
  96. //
  97. // Fill in our instance handle. We always return this so the 32-bit
  98. // code can free our library after having loaded it.
  99. //
  100. *lpsbcEnabled = FALSE;
  101. #ifdef DEBUG
  102. g_imSharedData.cbSize = sizeof(g_imSharedData);
  103. #endif
  104. *ppimSharedMem = (DWORD)MapSL(&g_imSharedData);
  105. ASSERT(*ppimSharedMem);
  106. if (version != DCS_MAKE_VERSION())
  107. {
  108. ERROR_OUT(("OSIInit16: failing, version mismatch 0x%lx (core) 0x%lx (dd)",
  109. version, DCS_MAKE_VERSION()));
  110. DC_QUIT;
  111. }
  112. // ONLY ALLOW ONE CLIENT TO INITIALIZE
  113. if (g_asMainWindow != NULL)
  114. {
  115. WARNING_OUT(("OSIInit16: mnmas16.dll was left around last time"));
  116. // If this task is no longer valid, then cleanup for it
  117. if (IsWindow(g_asMainWindow))
  118. {
  119. //
  120. // Uh oh. Somehow a previous version of NM is still around.
  121. // Do the safest thing--refuse to share.
  122. //
  123. ERROR_OUT(("OSIInit16: Another version of NetMeeting is still running!"));
  124. DC_QUIT;
  125. }
  126. // Cleanup (this is similar to the NT dd code)
  127. OSITerm16(TRUE);
  128. ASSERT(!g_asMainWindow);
  129. }
  130. //
  131. // Clear out shared IM memory.
  132. //
  133. g_imSharedData.imSuspended = FALSE;
  134. g_imSharedData.imControlled = FALSE;
  135. g_imSharedData.imPaused = FALSE;
  136. g_imSharedData.imUnattended = FALSE;
  137. g_asMainWindow = hwndCore;
  138. ASSERT(g_asMainWindow);
  139. g_hCoreTask = GetCurrentTask();
  140. g_osiDesktopWindow = GetDesktopWindow();
  141. ASSERT(g_osiDesktopWindow);
  142. //
  143. // DISPLAY DRIVER STUFF
  144. //
  145. hModDisplay = GetModuleHandle("DISPLAY");
  146. g_lpfnSetCursor = (SETCURSORPROC)GetProcAddress(hModDisplay,
  147. MAKEINTRESOURCE(ORD_OEMSETCURSOR));
  148. if (!hModDisplay || !g_lpfnSetCursor)
  149. {
  150. ERROR_OUT(("Couldn't find cursor entry points"));
  151. DC_QUIT;
  152. }
  153. // This doesn't always exist
  154. g_lpfnSaveBits = (SAVEBITSPROC)GetProcAddress(hModDisplay,
  155. MAKEINTRESOURCE(ORD_OEMSAVEBITS));
  156. //
  157. // KERNEL16 AND KERNEL32 STUFF
  158. //
  159. //
  160. // Get KRNL16's instance/module handle
  161. //
  162. g_hInstKrnl16 = LoadLibrary("KRNL386.EXE");
  163. ASSERT(g_hInstKrnl16);
  164. FreeLibrary(g_hInstKrnl16);
  165. g_hModKrnl16 = GetExePtr(g_hInstKrnl16);
  166. ASSERT(g_hModKrnl16);
  167. //
  168. // Get KERNEL32's instance/module handle
  169. //
  170. g_hInstKrnl32 = GetModuleHandle32("KERNEL32.DLL");
  171. ASSERT(g_hInstKrnl32);
  172. //
  173. // Get mapped 16-bit equivalent of KERNEL32's instance handle
  174. //
  175. g_hInstKrnl32MappedTo16 = MapInstance32(g_hInstKrnl32);
  176. ASSERT(g_hInstKrnl32MappedTo16);
  177. //
  178. // Get hold of MultiByteToWideChar() routine
  179. //
  180. g_lpfnAnsiToUni = (ANSITOUNIPROC)GetProcAddress32(g_hInstKrnl32,
  181. "MultiByteToWideChar");
  182. ASSERT(g_lpfnAnsiToUni);
  183. //
  184. // GDI16 AND GDI32 STUFF
  185. //
  186. //
  187. // Get GDI16's instance/module handle
  188. //
  189. g_hInstGdi16 = LoadLibrary("GDI.EXE");
  190. ASSERT(g_hInstGdi16);
  191. FreeLibrary(g_hInstGdi16);
  192. g_hModGdi16 = GetExePtr(g_hInstGdi16);
  193. ASSERT(g_hModGdi16);
  194. //
  195. // Get GDI32's instance/module handle
  196. //
  197. g_hInstGdi32 = GetModuleHandle32("GDI32.DLL");
  198. ASSERT(g_hInstGdi32);
  199. //
  200. // Get hold of GDI16 functions not exported but which are the target of
  201. // public GDI32 functions via flat thunks
  202. //
  203. if (!GetGdi32OnlyExport("ExtTextOutW", 0, (FARPROC FAR*)&g_lpfnExtTextOutW) ||
  204. !GetGdi32OnlyExport("TextOutW", 0, (FARPROC FAR*)&g_lpfnTextOutW) ||
  205. !GetGdi32OnlyExport("PolylineTo", 0, (FARPROC FAR*)&g_lpfnPolylineTo) ||
  206. !GetGdi32OnlyExport("PolyPolyline", 18, (FARPROC FAR*)&g_lpfnPolyPolyline))
  207. {
  208. ERROR_OUT(("Couldn't get hold of GDI32 routines"));
  209. DC_QUIT;
  210. }
  211. ASSERT(g_lpfnExtTextOutW);
  212. ASSERT(g_lpfnTextOutW);
  213. ASSERT(g_lpfnPolylineTo);
  214. ASSERT(g_lpfnPolyPolyline);
  215. //
  216. // USER16 and USER32 STUFF
  217. //
  218. //
  219. // Get USER16's instance/module handle
  220. //
  221. g_hInstUser16 = LoadLibrary("USER.EXE");
  222. ASSERT(g_hInstUser16);
  223. FreeLibrary(g_hInstUser16);
  224. g_hModUser16 = GetExePtr(g_hInstUser16);
  225. ASSERT(g_hModUser16);
  226. //
  227. // Get hold of USER32's instance handle. It has functions we
  228. // want to call which USER16 doesn't export.
  229. //
  230. g_hInstUser32 = GetModuleHandle32("USER32.DLL");
  231. ASSERT(g_hInstUser32);
  232. //
  233. // Get hold of USER16 functions not exported but which are the target of
  234. // public USER32 functions via flat thunks
  235. //
  236. if (!GetUser32OnlyExport("GetWindowThreadProcessId", (FARPROC FAR*)&g_lpfnGetWindowThreadProcessId))
  237. {
  238. ERROR_OUT(("Couldn't get hold of USER32 routines"));
  239. DC_QUIT;
  240. }
  241. ASSERT(g_lpfnGetWindowThreadProcessId);
  242. //
  243. // This exists in Memphis but not Win95
  244. //
  245. g_lpfnCDSEx = (CDSEXPROC)GetProcAddress(g_hModUser16, "ChangeDisplaySettingsEx");
  246. //
  247. // Allocate the shared memory we use to communicate with the 32-bit
  248. // share core.
  249. //
  250. ASSERT(!g_asSharedMemory);
  251. ASSERT(!g_poaData[0]);
  252. ASSERT(!g_poaData[1]);
  253. //
  254. // Allocate our blocks GMEM_SHARE so we aren't bound by the vagaries
  255. // of process ownership. We want our DLL to control them. Note that
  256. // we do the same thing with GDI objects we create--our module owns the.
  257. //
  258. // We use GMEM_FIXED since we map these to flat addresses for mnmcpi32.dll,
  259. // and we don't want the linear address of these memory blocks to move
  260. // afterwards.
  261. //
  262. hMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT | GMEM_SHARE, sizeof(SHM_SHARED_MEMORY));
  263. g_asSharedMemory = MAKELP(hMem, 0);
  264. hMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT | GMEM_SHARE, sizeof(OA_SHARED_DATA));
  265. g_poaData[0] = MAKELP(hMem, 0);
  266. hMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT | GMEM_SHARE, sizeof(OA_SHARED_DATA));
  267. g_poaData[1] = MAKELP(hMem, 0);
  268. if (!g_asSharedMemory ||
  269. !g_poaData[0] ||
  270. !g_poaData[1])
  271. {
  272. ERROR_OUT(("OSIInit16: couldn't allocate shared memory blocks"));
  273. DC_QUIT;
  274. }
  275. //
  276. // Get current screen attributes
  277. //
  278. g_oeStockPalette = GetStockObject(DEFAULT_PALETTE);
  279. g_osiScreenRect.left = 0;
  280. g_osiScreenRect.top = 0;
  281. g_osiScreenRect.right = GetSystemMetrics(SM_CXSCREEN);
  282. g_osiScreenRect.bottom = GetSystemMetrics(SM_CYSCREEN);
  283. g_osiScreenDC = CreateDC("DISPLAY", 0L, 0L, 0L);
  284. g_osiMemoryDC = CreateCompatibleDC(g_osiScreenDC);
  285. g_osiMemoryBMP = CreateCompatibleBitmap(g_osiScreenDC, 1, 1);
  286. if (!g_osiScreenDC || !g_osiMemoryDC || !g_osiMemoryBMP)
  287. {
  288. ERROR_OUT(("Couldn't get screen dc"));
  289. DC_QUIT;
  290. }
  291. SetObjectOwner(g_osiScreenDC, g_hInstAs16);
  292. SetObjectOwner(g_osiMemoryDC, g_hInstAs16);
  293. SetObjectOwner(g_osiMemoryBMP, g_hInstAs16);
  294. MakeObjectPrivate(g_osiMemoryBMP, TRUE);
  295. g_osiScreenBitsPlane = GetDeviceCaps(g_osiScreenDC, BITSPIXEL);
  296. g_osiScreenPlanes = GetDeviceCaps(g_osiScreenDC, PLANES);
  297. g_osiScreenBPP = (g_osiScreenBitsPlane * g_osiScreenPlanes);
  298. //
  299. // Get the color masks
  300. //
  301. g_osiScreenRedMask = 0x000000FF;
  302. g_osiScreenGreenMask = 0x0000FF00;
  303. g_osiScreenBlueMask = 0x00FF0000;
  304. //
  305. // Only displays with more than 8bpp (palettized) might have color
  306. // masks. Use our 1 pixel scratch bitmap to get them.
  307. //
  308. if (g_osiScreenBPP > 8)
  309. {
  310. DIB4 dib4T;
  311. //
  312. // Get the header
  313. //
  314. dib4T.bi.biSize = sizeof(BITMAPINFOHEADER);
  315. dib4T.bi.biBitCount = 0;
  316. GetDIBits(g_osiScreenDC, g_osiMemoryBMP, 0, 1, NULL, (LPBITMAPINFO)&dib4T.bi,
  317. DIB_RGB_COLORS);
  318. //
  319. // Get the mask
  320. //
  321. GetDIBits(g_osiScreenDC, g_osiMemoryBMP, 0, 1, NULL, (LPBITMAPINFO)&dib4T.bi,
  322. DIB_RGB_COLORS);
  323. if (dib4T.bi.biCompression == BI_BITFIELDS)
  324. {
  325. g_osiScreenRedMask = dib4T.ct[0];
  326. g_osiScreenGreenMask = dib4T.ct[1];
  327. g_osiScreenBlueMask = dib4T.ct[2];
  328. }
  329. }
  330. g_osiMemoryOld = SelectBitmap(g_osiMemoryDC, g_osiMemoryBMP);
  331. //
  332. // Initialize the bmiHeader so OEConvertColor() doesn't have to do it
  333. // over and over, when the header isn't touched by GDI.
  334. //
  335. g_osiScreenBMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  336. g_osiScreenBMI.bmiHeader.biPlanes = 1;
  337. g_osiScreenBMI.bmiHeader.biBitCount = g_osiScreenBPP;
  338. g_osiScreenBMI.bmiHeader.biCompression = BI_RGB;
  339. g_osiScreenBMI.bmiHeader.biSizeImage = 0;
  340. g_osiScreenBMI.bmiHeader.biXPelsPerMeter = 1000;
  341. g_osiScreenBMI.bmiHeader.biYPelsPerMeter = 1000;
  342. g_osiScreenBMI.bmiHeader.biClrUsed = 0;
  343. g_osiScreenBMI.bmiHeader.biClrImportant = 0;
  344. g_osiScreenBMI.bmiHeader.biWidth = 1;
  345. g_osiScreenBMI.bmiHeader.biHeight = 1;
  346. //
  347. // Init the various display driver components
  348. //
  349. BA_DDInit();
  350. if (!CM_DDInit(g_osiScreenDC))
  351. {
  352. ERROR_OUT(("CM failed to init"));
  353. DC_QUIT;
  354. }
  355. if (!SSI_DDInit())
  356. {
  357. ERROR_OUT(("SSI failed to init"));
  358. DC_QUIT;
  359. }
  360. if (!OE_DDInit())
  361. {
  362. ERROR_OUT(("OE failed to init"));
  363. DC_QUIT;
  364. }
  365. if (!IM_DDInit())
  366. {
  367. ERROR_OUT(("IM failed to init"));
  368. DC_QUIT;
  369. }
  370. if (!HET_DDInit())
  371. {
  372. ERROR_OUT(("HET failed to init"));
  373. DC_QUIT;
  374. }
  375. //
  376. // If we're here, all succeeded initializing
  377. //
  378. //
  379. // Map ptrs to flat addresses so they can be used in 32-bit code. This
  380. // can't fail unless kernel is so messed up Windows is about to keel
  381. // over and die.
  382. //
  383. ASSERT(ppSharedMem);
  384. *ppSharedMem = (DWORD)MapSL(g_asSharedMemory);
  385. ASSERT(*ppSharedMem);
  386. ASSERT(ppoaSharedMem);
  387. ppoaSharedMem[0] = (DWORD)MapSL(g_poaData[0]);
  388. ASSERT(ppoaSharedMem[0]);
  389. ppoaSharedMem[1] = (DWORD)MapSL(g_poaData[1]);
  390. ASSERT(ppoaSharedMem[1]);
  391. rc = TRUE;
  392. DC_EXIT_POINT:
  393. DebugExitBOOL(OSIInit16, rc);
  394. return(rc);
  395. }
  396. // --------------------------------------------------------------------------
  397. //
  398. // OSITerm16
  399. // Cleans up binary patcher, gdi + user patching, windows hooks, etc.
  400. //
  401. // We do this on normal OSI stop, and on catastrophic failure.
  402. //
  403. // --------------------------------------------------------------------------
  404. void WINAPI OSITerm16(BOOL fUnloading)
  405. {
  406. DebugEntry(OSITerm16);
  407. if (!g_hCoreTask)
  408. {
  409. // Nothing to cleanup.
  410. DC_QUIT;
  411. }
  412. //
  413. // Is the task that actually caused us to allocate our resources? In
  414. // other words, we don't want to clean up if
  415. // App A loads mnmas16.dll, and gets it inited
  416. // App B somehow starts up, loads mnmas16.dll, but mnmas16.dll
  417. // doesn't init for sharing because cProcesses is > 1
  418. // App B shuts down
  419. // App B calls OSITerm16
  420. //
  421. // So in the 'dll is really about to go away case', we always cleanup.
  422. // But in normal term of sharing, we cleanup if the current task is the
  423. // current one.
  424. //
  425. if (fUnloading || (g_hCoreTask == GetCurrentTask()))
  426. {
  427. //
  428. // Term other pieces that depend on layout of shared memory
  429. //
  430. HET_DDTerm();
  431. IM_DDTerm();
  432. OE_DDTerm();
  433. SSI_DDTerm();
  434. CM_DDTerm();
  435. //
  436. // Free memory blocks
  437. //
  438. if (g_poaData[1])
  439. {
  440. GlobalFree((HGLOBAL)SELECTOROF(g_poaData[1]));
  441. g_poaData[1] = NULL;
  442. }
  443. if (g_poaData[0])
  444. {
  445. GlobalFree((HGLOBAL)SELECTOROF(g_poaData[0]));
  446. g_poaData[0] = NULL;
  447. }
  448. if (g_asSharedMemory)
  449. {
  450. GlobalFree((HGLOBAL)SELECTOROF(g_asSharedMemory));
  451. g_asSharedMemory = NULL;
  452. }
  453. if (g_osiMemoryOld)
  454. {
  455. SelectBitmap(g_osiMemoryDC, g_osiMemoryOld);
  456. g_osiMemoryOld = NULL;
  457. }
  458. if (g_osiMemoryBMP)
  459. {
  460. SysDeleteObject(g_osiMemoryBMP);
  461. g_osiMemoryBMP = NULL;
  462. }
  463. if (g_osiMemoryDC)
  464. {
  465. DeleteDC(g_osiMemoryDC);
  466. g_osiMemoryDC = NULL;
  467. }
  468. if (g_osiScreenDC)
  469. {
  470. DeleteDC(g_osiScreenDC);
  471. g_osiScreenDC = NULL;
  472. }
  473. g_asMainWindow = NULL;
  474. g_hCoreTask = NULL;
  475. }
  476. DC_EXIT_POINT:
  477. DebugExitVOID(OSITerm16);
  478. }
  479. // --------------------------------------------------------------------------
  480. //
  481. // OSIFunctionRequest16
  482. //
  483. // Communication function with 32-bit MNMCPI32.DLL
  484. //
  485. // --------------------------------------------------------------------------
  486. BOOL WINAPI OSIFunctionRequest16(DWORD fnEscape, LPOSI_ESCAPE_HEADER lpOsiEsc,
  487. DWORD cbEscInfo)
  488. {
  489. BOOL rc = FALSE;
  490. DebugEntry(OSIFunctionRequest16);
  491. //
  492. // Check the data is long enough to store our standard escape header.
  493. // If it is not big enough this must be an escape request for another
  494. // driver.
  495. //
  496. if (cbEscInfo < sizeof(OSI_ESCAPE_HEADER))
  497. {
  498. ERROR_OUT(("Escape block not big enough"));
  499. DC_QUIT;
  500. }
  501. //
  502. // Check for our escape ID. If it is not our escape ID this must be an
  503. // escape request for another driver.
  504. //
  505. if (lpOsiEsc->identifier != OSI_ESCAPE_IDENTIFIER)
  506. {
  507. ERROR_OUT(("Bogus Escape header ID"));
  508. DC_QUIT;
  509. }
  510. else if (lpOsiEsc->version != DCS_MAKE_VERSION())
  511. {
  512. ERROR_OUT(("Mismatched display driver and NetMeeting"));
  513. DC_QUIT;
  514. }
  515. if ((fnEscape >= OSI_ESC_FIRST) && (fnEscape <= OSI_ESC_LAST))
  516. {
  517. rc = OSI_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  518. }
  519. else if ((fnEscape >= OSI_OE_ESC_FIRST) && (fnEscape <= OSI_OE_ESC_LAST))
  520. {
  521. rc = OE_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  522. }
  523. else if ((fnEscape >= OSI_HET_ESC_FIRST) && (fnEscape <= OSI_HET_ESC_LAST))
  524. {
  525. rc = HET_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  526. }
  527. else if ((fnEscape >= OSI_SBC_ESC_FIRST) && (fnEscape <= OSI_SBC_ESC_LAST))
  528. {
  529. // Do nothing
  530. }
  531. else if ((fnEscape >= OSI_SSI_ESC_FIRST) && (fnEscape <= OSI_SSI_ESC_LAST))
  532. {
  533. rc = SSI_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  534. }
  535. else if ((fnEscape >= OSI_CM_ESC_FIRST) && (fnEscape <= OSI_CM_ESC_LAST))
  536. {
  537. rc = CM_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  538. }
  539. else if ((fnEscape >= OSI_OA_ESC_FIRST) && (fnEscape <= OSI_OA_ESC_LAST))
  540. {
  541. rc = OA_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  542. }
  543. else if ((fnEscape >= OSI_BA_ESC_FIRST) && (fnEscape <= OSI_BA_ESC_LAST))
  544. {
  545. rc = BA_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  546. }
  547. else if ((fnEscape >= OSI_HET_WO_ESC_FIRST) && (fnEscape <= OSI_HET_WO_ESC_LAST))
  548. {
  549. rc = HET_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
  550. }
  551. else
  552. {
  553. ERROR_OUT(("Unknown function request"));
  554. }
  555. DC_EXIT_POINT:
  556. DebugExitBOOL(OSIFunctionRequest16, rc);
  557. return(rc);
  558. }
  559. //
  560. // OSI_DDProcessRequest()
  561. // Handles OSI generic escapes
  562. //
  563. BOOL OSI_DDProcessRequest
  564. (
  565. UINT fnEscape,
  566. LPOSI_ESCAPE_HEADER pResult,
  567. DWORD cbResult
  568. )
  569. {
  570. BOOL rc;
  571. DebugEntry(OSI_DDProcessRequest);
  572. switch (fnEscape)
  573. {
  574. case OSI_ESC_SYNC_NOW:
  575. {
  576. ASSERT(cbResult == sizeof(OSI_ESCAPE_HEADER));
  577. //
  578. // Resync with the 32-bit ring 3 core. This happens when
  579. // somebody joins or leaves a share.
  580. //
  581. BA_ResetBounds();
  582. OA_DDSyncUpdatesNow();
  583. rc = TRUE;
  584. }
  585. break;
  586. default:
  587. {
  588. ERROR_OUT(("Unrecognized OSI escape"));
  589. rc = FALSE;
  590. }
  591. break;
  592. }
  593. DebugExitBOOL(OSI_DDProcessRequest, rc);
  594. return(rc);
  595. }