Leaked source code of windows server 2003
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.

668 lines
18 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: MAIN.C
  3. *
  4. * PURPOSE: WinMain, WEP and some other misc routines
  5. *
  6. * Created: 1991
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Srinik (04/01/91) Pulled some routines, into this, from ole.c.
  12. * curts Create portable version for win16/32.
  13. *
  14. \***************************************************************************/
  15. #include <windows.h>
  16. #include <reghelp.hxx>
  17. #include "dll.h"
  18. #include "strsafe.h"
  19. #ifndef WF_WLO
  20. #define WF_WLO 0x8000
  21. #endif
  22. // ordinal number new win31 API IsTask
  23. #define ORD_IsTask 320
  24. #define NUM_DLL 30 /* space for this many DLL_ENTRYs is created on */
  25. /* each alloc/realloc */
  26. OLECLIPFORMAT cfOwnerLink = 0; // global variables for clip frmats
  27. OLECLIPFORMAT cfObjectLink = 0;
  28. OLECLIPFORMAT cfLink = 0;
  29. OLECLIPFORMAT cfNative = 0;
  30. OLECLIPFORMAT cfBinary = 0;
  31. OLECLIPFORMAT cfFileName = 0;
  32. OLECLIPFORMAT cfNetworkName = 0;
  33. ATOM aStdHostNames;
  34. ATOM aStdTargetDevice ;
  35. ATOM aStdDocDimensions;
  36. ATOM aStdDocName;
  37. ATOM aStdColorScheme;
  38. ATOM aNullArg = 0;
  39. ATOM aSave;
  40. ATOM aChange;
  41. ATOM aClose;
  42. ATOM aSystem;
  43. ATOM aOle;
  44. ATOM aClipDoc;
  45. ATOM aPackage;
  46. // Used in work around for MSDraw bug
  47. ATOM aMSDraw;
  48. extern LPCLIENTDOC lpHeadDoc;
  49. extern LPCLIENTDOC lpTailDoc;
  50. extern RENDER_ENTRY stdRender[];
  51. HANDLE hInstDLL;
  52. /* HANDLE hDllTable; !!! Add this when bug in WEP is fixed */
  53. DLL_ENTRY lpDllTable[NUM_DLL]; //!!! change this when WEP bug is fixed
  54. DWORD dllTableSize;
  55. int iLast = 0;
  56. int iMax = NUM_DLL -1;
  57. int iUnloadableDll = 0; // index to handler than can be freed up
  58. char packageClass[] = "Package";
  59. // For QuerySize() API & methods.
  60. extern OLESTREAMVTBL dllStreamVtbl;
  61. extern CLIENTDOC lockDoc;
  62. // LOWWORD - BYTE 0 major verision, BYTE1 minor version,
  63. // HIWORD reserved
  64. DWORD dwOleVer = 0x0901L; // change this when we want to update dll version
  65. // number
  66. WORD wReleaseVer = 0x0001; // This is used while object is being saved to
  67. // file. There is no need to change this value
  68. // whenever we change ole dll version number
  69. static BOOL bLibInit = FALSE;
  70. HANDLE hModule;
  71. #define MAX_HIMETRIC 0x7FFF
  72. int maxPixelsX = MAX_HIMETRIC;
  73. int maxPixelsY = MAX_HIMETRIC;
  74. void SetMaxPixel (void);
  75. VOID FAR PASCAL WEP (int);
  76. //////////////////////////////////////////////////////////////////////////////
  77. //
  78. // int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine)
  79. //
  80. // The main library entry point. This routine is called when the library
  81. // is loaded.
  82. //
  83. // Arguments:
  84. //
  85. // hInst - dll's instance handle
  86. // wDataSeg - DS register value
  87. // cbHeapSize - heap size defined def file
  88. // lpszCmdLine - command line info
  89. //
  90. // Returns:
  91. //
  92. // 0 - failure
  93. // 1 - success
  94. //
  95. // Effects:
  96. //
  97. //////////////////////////////////////////////////////////////////////////////
  98. #ifdef WIN32
  99. BOOL LibMain(
  100. HANDLE hInst,
  101. ULONG Reason,
  102. PCONTEXT Context
  103. #endif // WIN32
  104. ){
  105. WNDCLASS wc;
  106. int i;
  107. #ifdef WIN32
  108. char szDocClass[] = "OleDocWndClass" ;
  109. char szSrvrClass[] = "OleSrvrWndClass" ;
  110. #endif
  111. Puts("LibMain");
  112. #ifdef WIN32 // begin WIN32
  113. UNREFERENCED_PARAMETER(Context);
  114. if (Reason == DLL_PROCESS_DETACH)
  115. {
  116. WEP(0);
  117. UnregisterClass (szDocClass, hInst) ;
  118. UnregisterClass (szSrvrClass, hInst) ;
  119. return TRUE;
  120. }
  121. else if (Reason != DLL_PROCESS_ATTACH)
  122. return TRUE;
  123. #endif // end WIN32
  124. bLibInit = TRUE;
  125. hInstDLL = hInst;
  126. hModule = GetModuleHandle ("OLECLI");
  127. // REGISTER LINK FORMAT
  128. cfObjectLink = (OLECLIPFORMAT)RegisterClipboardFormat("ObjectLink");
  129. cfLink = (OLECLIPFORMAT)RegisterClipboardFormat("Link");
  130. cfOwnerLink = (OLECLIPFORMAT)RegisterClipboardFormat("OwnerLink");
  131. cfNative = (OLECLIPFORMAT)RegisterClipboardFormat("Native");
  132. cfBinary = (OLECLIPFORMAT)RegisterClipboardFormat("Binary");
  133. cfFileName = (OLECLIPFORMAT)RegisterClipboardFormat("FileName");
  134. cfNetworkName = (OLECLIPFORMAT)RegisterClipboardFormat("NetworkName");
  135. if (!(cfObjectLink && cfOwnerLink && cfNative && cfLink))
  136. return 0;
  137. // SET UP OLEWNDCLASS
  138. wc.style = 0;
  139. wc.lpfnWndProc = DocWndProc;
  140. wc.cbClsExtra = 0;
  141. wc.cbWndExtra = sizeof(LONG_PTR); //we are storing longs
  142. wc.hInstance = hInst;
  143. wc.hIcon = NULL;
  144. wc.hCursor = NULL;
  145. wc.hbrBackground= NULL;
  146. wc.lpszMenuName = NULL;
  147. wc.lpszClassName= szDocClass;
  148. if (!RegisterClass(&wc))
  149. return 0;
  150. wc.lpfnWndProc = SrvrWndProc;
  151. wc.lpszClassName = szSrvrClass ;
  152. if (!RegisterClass(&wc))
  153. return 0;
  154. /*
  155. // !!! Add this when bug in WEP is fixed.
  156. // Allocate memory for DLL table
  157. dllTableSize = NUM_DLL * sizeof(DLL_ENTRY);
  158. if (!(hDllTable = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
  159. dllTableSize)))
  160. return 0;
  161. if (!(lpDllTable = (DLL_ENTRY FAR *) GlobalLock (hDllTable)))
  162. return 0;
  163. */
  164. // !!! remove the following when WEP bug is fixed
  165. for (i = 0; i < NUM_DLL; i++)
  166. lpDllTable[i].aDll = (ATOM)0;
  167. // !!! BEGIN hack for Pbrush.
  168. lpDllTable[0].hDll = NULL;
  169. lpDllTable[0].aDll = GlobalAddAtom ((LPSTR) "ole");
  170. lpDllTable[0].Load = PbLoadFromStream;
  171. lpDllTable[0].Clip = PbCreateFromClip;
  172. lpDllTable[0].Link = PbCreateLinkFromClip;
  173. lpDllTable[0].Create = PbCreate;
  174. lpDllTable[0].CreateFromTemplate = PbCreateFromTemplate;
  175. lpDllTable[0].CreateFromFile = PbCreateFromFile;
  176. lpDllTable[0].CreateLinkFromFile = PbCreateLinkFromFile;
  177. lpDllTable[0].CreateInvisible = PbCreateInvisible;
  178. // !!! END hack for pbrush
  179. // For ObjectSize API
  180. dllStream.lpstbl = (LPOLESTREAMVTBL) &dllStreamVtbl;
  181. dllStream.lpstbl->Put = DllPut;
  182. // add the atoms required.
  183. aStdDocName = GlobalAddAtom ((LPSTR)"StdDocumentName");
  184. aSave = GlobalAddAtom ((LPSTR)"Save");
  185. aChange = GlobalAddAtom ((LPSTR)"Change");
  186. aClose = GlobalAddAtom ((LPSTR)"Close");
  187. aSystem = GlobalAddAtom ((LPSTR)"System");
  188. aOle = GlobalAddAtom ((LPSTR)"OLEsystem");
  189. aPackage = GlobalAddAtom ((LPSTR) packageClass);
  190. // Used in work around for MSDraw bug
  191. aMSDraw = GlobalAddAtom ((LPSTR) "MSDraw");
  192. // clipboard document name atom
  193. aClipDoc = GlobalAddAtom ((LPSTR)"Clipboard");
  194. stdRender[0].aClass = GlobalAddAtom ("METAFILEPICT");
  195. stdRender[1].aClass = GlobalAddAtom ("DIB");
  196. stdRender[2].aClass = GlobalAddAtom ("BITMAP");
  197. stdRender[3].aClass = GlobalAddAtom ("ENHMETAFILE");
  198. SetMaxPixel();
  199. return 1;
  200. }
  201. //////////////////////////////////////////////////////////////////////////////
  202. //
  203. // VOID FAR PASCAL WEP (nParameter)
  204. //
  205. // Called just before the library is being unloaded. Delete all the atoms
  206. // added by this dll and also frees up all unloaded handler dlls.
  207. //
  208. // Arguments:
  209. //
  210. // nParameter - Termination code
  211. //
  212. // Returns:
  213. //
  214. // none
  215. //
  216. // Effects:
  217. //
  218. //////////////////////////////////////////////////////////////////////////////
  219. VOID FAR PASCAL WEP (int nParameter)
  220. {
  221. int i;
  222. Puts("LibExit");
  223. #ifdef WIN32 // begin WIN32
  224. UNREFERENCED_PARAMETER(nParameter);
  225. DEBUG_OUT ("---L&E DLL EXIT---\n",0)
  226. #endif // end WIN32
  227. // case when the DLLs are missing
  228. if (!bLibInit)
  229. return;
  230. // Delete atoms added by us
  231. for (i = 0; i < NUM_RENDER; i++) {
  232. if (stdRender[i].aClass)
  233. GlobalDeleteAtom (stdRender[i].aClass);
  234. }
  235. if (aStdDocName)
  236. GlobalDeleteAtom (aStdDocName);
  237. if (aSave)
  238. GlobalDeleteAtom (aSave);
  239. if (aChange)
  240. GlobalDeleteAtom (aChange);
  241. if (aClose)
  242. GlobalDeleteAtom (aClose);
  243. if (aSystem)
  244. GlobalDeleteAtom (aSystem);
  245. if (aOle)
  246. GlobalDeleteAtom (aOle);
  247. if (aPackage)
  248. GlobalDeleteAtom (aPackage);
  249. if (aClipDoc)
  250. GlobalDeleteAtom (aClipDoc);
  251. if (aMSDraw)
  252. GlobalDeleteAtom (aMSDraw);
  253. // Free handler dlls if there are any still loaded. Entry 0 is used for
  254. // Pbrush handler which is part of this dll.
  255. for (i = 0; i <= iLast; i++) {
  256. if (lpDllTable[i].aDll)
  257. GlobalDeleteAtom (lpDllTable[i].aDll);
  258. if (lpDllTable[i].hDll)
  259. FreeLibrary (lpDllTable[i].hDll);
  260. }
  261. /* !!! Add this when bug in WEP is fixed
  262. if (lpDllTable)
  263. GlobalUnlock (hDllTable);
  264. if (hDllTable)
  265. GlobalFree (hDllTable);
  266. */
  267. }
  268. int FARINTERNAL LoadDll (LPCSTR lpClass)
  269. {
  270. char str[MAX_STR];
  271. char str1[MAX_STR];
  272. ATOM aDll = (ATOM)0;
  273. int index;
  274. int iEmpty;
  275. BOOL found = FALSE;
  276. HANDLE hDll;
  277. LONG cb = MAX_STR;
  278. if (!lstrcmpi (lpClass, "Pbrush"))
  279. return 0;
  280. if (FAILED(StringCchCopy(str, sizeof(str)/sizeof(str[0]), lpClass)))
  281. return 0;
  282. if (FAILED(StringCchCat(str, sizeof(str)/sizeof(str[0]), "\\protocol\\StdFileEditing\\handler32")))
  283. return 0;
  284. if (QueryClassesRootValueA (str, str1, &cb))
  285. return INVALID_INDEX;
  286. if (aDll = GlobalFindAtom (str1)) {
  287. for (index = 1; index <= iLast && index < sizeof(lpDllTable)/sizeof(lpDllTable[0]); index++) {
  288. if (lpDllTable[index].aDll == aDll) { // Dll already loaded
  289. lpDllTable[index].cObj ++;
  290. if (index == iUnloadableDll) {
  291. // since the object count is not zero anymore, this
  292. // handler can not be freed up.
  293. iUnloadableDll = 0;
  294. }
  295. return index;
  296. }
  297. }
  298. }
  299. aDll = GlobalAddAtom (str1);
  300. // Look for an empty entry
  301. for (iEmpty = 1; iEmpty <= iLast && iEmpty < sizeof(lpDllTable)/sizeof(lpDllTable[0]); iEmpty++) {
  302. if (!lpDllTable[iEmpty].aDll) {
  303. found = TRUE;
  304. break;
  305. }
  306. }
  307. if (iEmpty > iMax)
  308. goto errLoad;
  309. /*
  310. if (!found) {// no empty entry exists create a new one if necessary.
  311. if (iEmpty > iMax) {
  312. dllTableSize += (blockSize = NUM_DLL * sizeof(DLL_ENTRY));
  313. hTable = GlobalReAlloc (hDllTable, dllTableSize,
  314. GMEM_MOVEABLE | GMEM_ZEROINIT);
  315. if (hTable == hDllTable)
  316. iMax += NUM_DLL;
  317. else {
  318. dllTableSize -= blockSize;
  319. iEmpty = INVALID_INDEX;
  320. }
  321. }
  322. }
  323. */
  324. #ifdef WIN32
  325. hDll = LoadLibrary ((LPSTR) str1);
  326. #endif
  327. if (MAPVALUE(hDll < 32, !hDll))
  328. goto errLoad;
  329. if (!(lpDllTable[iEmpty].Load = (_LOAD)GetProcAddress(hDll,
  330. "DllLoadFromStream")))
  331. goto errLoad;
  332. if (!(lpDllTable[iEmpty].Clip = (_CLIP)GetProcAddress (hDll,
  333. "DllCreateFromClip")))
  334. goto errLoad;
  335. if (!(lpDllTable[iEmpty].Link = (_LINK)GetProcAddress (hDll,
  336. "DllCreateLinkFromClip")))
  337. goto errLoad;
  338. if (!(lpDllTable[iEmpty].CreateFromTemplate = (_CREATEFROMTEMPLATE)
  339. GetProcAddress (hDll,
  340. "DllCreateFromTemplate")))
  341. goto errLoad;
  342. if (!(lpDllTable[iEmpty].Create = (_CREATE)GetProcAddress (hDll,
  343. "DllCreate")))
  344. goto errLoad;
  345. if (!(lpDllTable[iEmpty].CreateFromFile = (_CREATEFROMFILE)GetProcAddress (hDll,
  346. "DllCreateFromFile")))
  347. goto errLoad;
  348. if (!(lpDllTable[iEmpty].CreateLinkFromFile = (_CREATELINKFROMFILE)GetProcAddress (hDll,
  349. "DllCreateLinkFromFile")))
  350. goto errLoad;
  351. lpDllTable[iEmpty].CreateInvisible = (_CREATEINVISIBLE)GetProcAddress (hDll,
  352. "DllCreateInvisible");
  353. lpDllTable[iEmpty].aDll = aDll;
  354. lpDllTable[iEmpty].cObj = 1;
  355. lpDllTable[iEmpty].hDll = hDll;
  356. if (iEmpty > iLast)
  357. iLast++;
  358. return iEmpty;
  359. errLoad:
  360. if (aDll)
  361. GlobalDeleteAtom (aDll);
  362. if (MAPVALUE(hDll >= 32, !hDll))
  363. FreeLibrary (hDll);
  364. return INVALID_INDEX;
  365. }
  366. // unload the the handler that can be free up (whose object count is NULL)
  367. void FARINTERNAL UnloadDll ()
  368. {
  369. if (!iUnloadableDll)
  370. return;
  371. if (iUnloadableDll == iLast)
  372. iLast--;
  373. if (iUnloadableDll >= sizeof(lpDllTable)/sizeof(lpDllTable[0]))
  374. return;
  375. if (lpDllTable[iUnloadableDll].aDll)
  376. GlobalDeleteAtom (lpDllTable[iUnloadableDll].aDll);
  377. lpDllTable[iUnloadableDll].aDll = (ATOM)0;
  378. FreeLibrary (lpDllTable[iUnloadableDll].hDll);
  379. lpDllTable[iUnloadableDll].hDll = NULL;
  380. iUnloadableDll = 0;
  381. }
  382. //
  383. // Reduce the object count of the handler, refered to by the index, by one.
  384. // If the object count becomes NULL, free up the handler that is ready to be
  385. // freed (refered to by index iUnloadableDll), and then make this handler the
  386. // freeable one.
  387. //
  388. // As you can see we are trying to implement a simple mechanism of caching.
  389. //
  390. void FARINTERNAL DecreaseHandlerObjCount (int iTable)
  391. {
  392. if (!iTable)
  393. return;
  394. if (iTable != INVALID_INDEX) {
  395. ASSERT (lpDllTable[iTable].cObj, "Handler Obj count is already NULL");
  396. if (!--lpDllTable[iTable].cObj) {
  397. UnloadDll ();
  398. iUnloadableDll = iTable;
  399. }
  400. }
  401. }
  402. /***************************** Public Function ****************************\
  403. *
  404. * OLESTATUS FARINTERNAL CreatePictFromClip (lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, lpClass, ctype)
  405. *
  406. * CreatePictFromClip: This function creates the LP to an object
  407. * from the clipboard. It will try to create a static picture object if
  408. * it understands any rendering formats on the clipboard. Currently, it
  409. * understands only bitmaps and metafiles.
  410. *
  411. * Effects:
  412. *
  413. * History:
  414. * Wrote it.
  415. \***************************************************************************/
  416. OLESTATUS FARINTERNAL CreatePictFromClip (
  417. LPOLECLIENT lpclient,
  418. LHCLIENTDOC lhclientdoc,
  419. LPSTR lpobjname,
  420. LPOLEOBJECT FAR * lplpobj,
  421. OLEOPT_RENDER optRender,
  422. OLECLIPFORMAT cfFormat,
  423. LPSTR lpClass,
  424. LONG objType
  425. ){
  426. OLESTATUS retVal = OLE_ERROR_OPTION;
  427. *lplpobj = NULL;
  428. if (optRender == olerender_none)
  429. return OLE_OK;
  430. else if (optRender == olerender_format) {
  431. switch (cfFormat) {
  432. case 0:
  433. return OLE_ERROR_FORMAT;
  434. case CF_ENHMETAFILE:
  435. return EmfPaste (lpclient, lhclientdoc, lpobjname,
  436. lplpobj, objType);
  437. case CF_METAFILEPICT:
  438. return MfPaste (lpclient, lhclientdoc, lpobjname,
  439. lplpobj, objType);
  440. case CF_DIB:
  441. return DibPaste (lpclient, lhclientdoc, lpobjname,
  442. lplpobj, objType);
  443. case CF_BITMAP:
  444. return BmPaste (lpclient, lhclientdoc, lpobjname,
  445. lplpobj, objType);
  446. default:
  447. return GenPaste (lpclient, lhclientdoc, lpobjname, lplpobj,
  448. lpClass, cfFormat, objType);
  449. }
  450. }
  451. else if (optRender == olerender_draw) {
  452. cfFormat = (OLECLIPFORMAT)EnumClipboardFormats (0);
  453. while ((cfFormat) && (retVal > OLE_WAIT_FOR_RELEASE)) {
  454. switch (cfFormat) {
  455. case CF_ENHMETAFILE:
  456. retVal = EmfPaste (lpclient, lhclientdoc, lpobjname,
  457. lplpobj, objType);
  458. break;
  459. case CF_METAFILEPICT:
  460. retVal = MfPaste (lpclient, lhclientdoc,
  461. lpobjname, lplpobj, objType);
  462. break;
  463. case CF_DIB:
  464. retVal = DibPaste (lpclient, lhclientdoc,
  465. lpobjname, lplpobj, objType);
  466. break;
  467. case CF_BITMAP:
  468. retVal = BmPaste (lpclient, lhclientdoc,
  469. lpobjname, lplpobj, objType);
  470. break;
  471. }
  472. cfFormat = (OLECLIPFORMAT)EnumClipboardFormats (cfFormat);
  473. }
  474. }
  475. return retVal;
  476. }
  477. OLESTATUS FARINTERNAL CreatePackageFromClip (
  478. LPOLECLIENT lpclient,
  479. LHCLIENTDOC lhclientdoc,
  480. LPSTR lpobjname,
  481. LPOLEOBJECT FAR * lplpobj,
  482. OLEOPT_RENDER optRender,
  483. OLECLIPFORMAT cfFormat,
  484. LONG objType
  485. ){
  486. char file[MAX_STR+6];
  487. HANDLE hData;
  488. LPSTR lpFileName;
  489. if (!(hData = GetClipboardData (cfFileName))
  490. || !(lpFileName = GlobalLock (hData)))
  491. return OLE_ERROR_CLIPBOARD;
  492. if (objType == OT_LINK) {
  493. StringCchCopy(file, sizeof(file)/sizeof(file[0]), lpFileName);
  494. StringCchCat(file, sizeof(file)/sizeof(file[0]), "/Link");
  495. lpFileName = (LPSTR) file;
  496. }
  497. GlobalUnlock (hData);
  498. return CreateEmbLnkFromFile (lpclient, packageClass, lpFileName,
  499. NULL, lhclientdoc, lpobjname, lplpobj,
  500. optRender, cfFormat, OT_EMBEDDED);
  501. }
  502. void FARINTERNAL RemoveLinkStringFromTopic (
  503. LPOBJECT_LE lpobj
  504. ){
  505. char buf[MAX_STR+6];
  506. int i = 0;
  507. if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf))) {
  508. // scan the topic for "/Link"
  509. while (buf[i] != '/') {
  510. if (!buf[i])
  511. return;
  512. i++;
  513. }
  514. buf[i] = '\0';
  515. if (lpobj->topic)
  516. GlobalDeleteAtom (lpobj->topic);
  517. lpobj->topic = GlobalAddAtom (buf);
  518. }
  519. }
  520. void SetMaxPixel ()
  521. {
  522. HDC hdc;
  523. // find out the pixel equivalent of MAX_HIMETRIC in X and Y directions
  524. if (hdc = GetDC (NULL)) {
  525. maxPixelsX = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSX),
  526. 2540);
  527. maxPixelsY = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSY),
  528. 2540);
  529. ReleaseDC (NULL, hdc);
  530. }
  531. }