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.

448 lines
12 KiB

  1. /*----------------------------------------------------------
  2. Purpose: Unix-menus related functions.
  3. */
  4. #include <tchar.h>
  5. #include <process.h>
  6. #include "priv.h"
  7. #pragma hdrstop
  8. #ifdef UNIX
  9. #include "unixstuff.h"
  10. #include "resource.h"
  11. DWORD g_dwTlsInfo = 0xffffffff;
  12. void UnixStuffInit()
  13. {
  14. g_dwTlsInfo = TlsAlloc();
  15. }
  16. // This is OK since we use Old Nt40 Shell32.
  17. STDAPI_(BOOL) WINAPI SHGetFileClassKey (LPCTSTR szFile, HKEY * phkey, HKEY * phkeyBase);
  18. STDAPI_(VOID) WINAPI SHCloseClassKey (HKEY hkey);
  19. void InitializeExplorerClass();
  20. STDAPI_(BOOL) FileHasProperAssociation (LPCTSTR path)
  21. {
  22. BOOL bRet = FALSE;
  23. HKEY hkClass = NULL, hkBase = NULL;
  24. if( SHGetFileClassKey(path, &hkClass, &hkBase ) )
  25. {
  26. bRet = TRUE;
  27. if(hkClass) SHCloseClassKey( hkClass );
  28. if(hkBase ) SHCloseClassKey( hkBase );
  29. }
  30. return bRet;
  31. }
  32. #define WMC_UNIX_NEWWINDOW (WM_USER + 0x0400)
  33. LRESULT HandleCopyDataUnix(CShellBrowser2* psb, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  34. {
  35. switch (wParam)
  36. {
  37. case WMC_DISPATCH:
  38. {
  39. DDENAVIGATESTRUCT *pDDENav;
  40. LPSTR szURL;
  41. LRESULT lres = 0;
  42. szURL = (LPSTR)((COPYDATASTRUCT*)lParam)->lpData;
  43. pDDENav = new(DDENAVIGATESTRUCT);
  44. if (pDDENav)
  45. {
  46. pDDENav->wszUrl = (LPWSTR)LocalAlloc(LPTR, (lstrlenA(szURL) + 1) * sizeof(WCHAR));
  47. if (pDDENav->wszUrl)
  48. {
  49. pDDENav->transID = 0;
  50. MultiByteToWideChar(CP_ACP, 0, szURL, lstrlenA(szURL), pDDENav->wszUrl, lstrlenA(szURL));
  51. lres = psb->WndProcBS(hwnd, WMC_DISPATCH, (WPARAM)DSID_NAVIGATEIEBROWSER, (LPARAM)pDDENav);
  52. LocalFree(pDDENav->wszUrl);
  53. }
  54. delete(pDDENav);
  55. }
  56. return lres;
  57. }
  58. case WMC_UNIX_NEWWINDOW:
  59. {
  60. LPSTR szURL;
  61. WCHAR wszURL[MAX_URL_STRING];
  62. LPITEMIDLIST pidl;
  63. HRESULT hres = S_OK;
  64. szURL = (LPSTR)((COPYDATASTRUCT*)lParam)->lpData;
  65. if (szURL[0])
  66. {
  67. MultiByteToWideChar(CP_ACP, 0, szURL, lstrlenA(szURL) + 1, wszURL, ARRAYSIZE(wszURL));
  68. }
  69. else
  70. {
  71. hres = _GetStdLocation(wszURL, ARRAYSIZE(wszURL), DVIDM_GOHOME);
  72. }
  73. if (SUCCEEDED(hres))
  74. {
  75. hres = psb->IEParseDisplayName(CP_ACP, wszURL, &pidl);
  76. if (SUCCEEDED(hres))
  77. hres = psb->BrowseObject(pidl, SBSP_NEWBROWSER);
  78. }
  79. ILFree(pidl);
  80. return hres;
  81. }
  82. default:
  83. return FALSE;
  84. }
  85. }
  86. void StoreIEWindowInfo( HWND hwnd )
  87. {
  88. if (g_dwTlsInfo != 0xffffffff)
  89. {
  90. TlsSetValue( g_dwTlsInfo, hwnd );
  91. }
  92. }
  93. HWND GetIEWindowOnThread( )
  94. {
  95. if (g_dwTlsInfo != 0xffffffff)
  96. {
  97. return (HWND)TlsGetValue( g_dwTlsInfo );
  98. }
  99. return (HWND)0;
  100. }
  101. void PrintIEVersion()
  102. {
  103. CHAR aboutInf[MAX_PATH] = "", *ptr;
  104. // Get the version information from Shlwapi
  105. SHAboutInfoA( aboutInf, sizeof(aboutInf) );
  106. ptr = StrChrA( aboutInf, '~' );
  107. if( ptr ) *ptr = '\0';
  108. printf("Internet Explorer %s ; Copyright (c) 1995-98 Microsoft Corp.\n", aboutInf);
  109. }
  110. void PrintIEHelp()
  111. {
  112. CHAR aboutInf[MAX_PATH] = "", *ptr;
  113. // Get the version information from Shlwapi
  114. SHAboutInfoA( aboutInf, sizeof(aboutInf) );
  115. ptr = StrChrA( aboutInf, '~' );
  116. if( ptr ) *ptr = '\0';
  117. printf("Internet Explorer %s :\n\tUsage : iexplorer [ options ... ] [ URL ]\n\n", aboutInf);
  118. printf("Valid command line options :\n");
  119. printf("\t-root : Opens Internet Explorer, connects to default home page.\n");
  120. printf("\t-slf : Opens Internet Explorer, loads home page from cache.\n");
  121. printf("\t-k : Kiosk mode.\n");
  122. printf("\t-version : Prints out the version of Internet Explorer.\n");
  123. printf("\t-v : Same as -version.\n\n");
  124. printf("URL - Name that will be interpreted as either a URL or a file to be loaded.\n");
  125. }
  126. BOOL CheckForInvalidOptions( LPCTSTR inCmdLine )
  127. {
  128. LPTSTR pszCmdLine = (LPTSTR) inCmdLine;
  129. TCHAR * knownOptions[] = { TEXT("help"), TEXT("embedding"), TEXT("slf"), TEXT("root"), TEXT("k"), TEXT("version"), TEXT("v"), TEXT("nohome") };
  130. int nCountOptions = sizeof(knownOptions)/sizeof(TCHAR *);
  131. while( 1 )
  132. {
  133. TCHAR * pos = StrChr( pszCmdLine, TEXT('-') );
  134. if( pos )
  135. {
  136. BOOL bFound = FALSE;
  137. pos++;
  138. TCHAR * option = pos;
  139. while( *pos && *pos != TEXT(' ') ) pos++;
  140. // Check for empty option or embedded '-'
  141. if( pos != option &&
  142. ( (option <= inCmdLine+1) || (*(option-2) == TEXT(' ')) ) )
  143. {
  144. for(int i = 0; i<nCountOptions; i++ )
  145. if(!StrCmpNI( option, knownOptions[i],
  146. lstrlen(knownOptions[i])))
  147. {
  148. bFound = TRUE;
  149. break;
  150. }
  151. if( bFound == FALSE )
  152. {
  153. *pos = TCHAR('\0');
  154. printf("Unknown option : %s\n\n", option);
  155. PrintIEHelp();
  156. return bFound;
  157. }
  158. }
  159. pszCmdLine = pos;
  160. }
  161. else break;
  162. }
  163. return TRUE;
  164. }
  165. #ifdef NO_MARSHALLING
  166. // We have multiple windows on a thread.
  167. // So we store the list of psbs in a THREADWINDOWINFO *
  168. // in each thread (stored in a TLS).
  169. #define DWSTYLE WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN
  170. extern "C" DWORD g_TLSThreadWindowInfo = ~0;
  171. STDAPI CoMarshalInterfaceDummy( IStream *pStm, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags )
  172. {
  173. if (pStm)
  174. {
  175. HRESULT hres;
  176. ULONG pcbWrite = 0;
  177. pStm->Seek(c_li0, STREAM_SEEK_SET, NULL);
  178. hres = pStm->Write( &pUnk, SIZEOF(pUnk), &pcbWrite );
  179. pUnk->AddRef();
  180. return hres;
  181. }
  182. return E_FAIL;
  183. }
  184. LPCTSTR _GetExplorerClassName(UINT uFlags);
  185. EXTERN_C void IEFrameNewWindowSameThread(IETHREADPARAM* piei)
  186. {
  187. DWORD uFlags = piei->uFlags;
  188. THREADWINDOWINFO *lpThreadWindowInfo;
  189. #ifdef NO_MARSHALLING
  190. BOOL fFirstTime = FALSE;
  191. #endif
  192. ASSERT(piei);
  193. if (!piei)
  194. return;
  195. LPWSTR pszCloseEvent = NULL;
  196. if (uFlags & COF_FIREEVENTONCLOSE)
  197. {
  198. ASSERT(piei->szCloseEvent[0]);
  199. pszCloseEvent = StrDup(piei->szCloseEvent);
  200. }
  201. // We shouldn't be the first ones
  202. ASSERT(~0 != g_TLSThreadWindowInfo)
  203. lpThreadWindowInfo = (THREADWINDOWINFO *) TlsGetValue(g_TLSThreadWindowInfo);
  204. ASSERT(lpThreadWindowInfo);
  205. if (!lpThreadWindowInfo)
  206. {
  207. #ifdef NO_MARSHALLING
  208. if (!(lpThreadWindowInfo = InitializeThreadInfoStructs()))
  209. goto Done;
  210. fFirstTime = TRUE;
  211. #else
  212. goto Done;
  213. #endif
  214. }
  215. #ifdef DEBUG_EXPLORER
  216. piei->wv.bTree = TRUE;
  217. piei->TreeSplit = 200; // some random default
  218. #endif
  219. TraceMsg(TF_COCREATE, "IEFrameNewWindowSameThread calling CreateWindowEx");
  220. #ifdef NO_MARSHALLING
  221. if (!piei->fOnIEThread)
  222. InitializeExplorerClass();
  223. #endif
  224. LPCTSTR pszClass;
  225. HMENU hmenu = CreateMenu();
  226. HWND hwnd = CreateWindowEx(WS_EX_WINDOWEDGE,
  227. _GetExplorerClassName(piei->uFlags), NULL, DWSTYLE,
  228. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  229. NULL,
  230. hmenu,
  231. HINST_THISDLL, piei);
  232. if (uFlags & COF_HELPMODE )
  233. {
  234. RECT rc;
  235. GetWindowRect( hwnd, &rc );
  236. SetWindowPos ( hwnd, 0, rc.left, rc.top, BROWSER_DEFAULT_WIDTH * 3 /4, BROWSER_DEFAULT_HEIGHT * 3 / 4, SWP_NOZORDER );
  237. }
  238. if (hwnd)
  239. {
  240. // Enable File Manager drag-drop for win16
  241. DragAcceptFiles(hwnd, TRUE);
  242. CShellBrowser2* psb = (CShellBrowser2*)GetWindowLong(hwnd, 0);
  243. if (psb)
  244. {
  245. // We are string another refrence to this object in
  246. // ThreadInfo Stuctures, so AddRef.
  247. psb->AddRef();
  248. psb->_AfterWindowCreated(piei);
  249. #ifdef NO_MARSHALLING
  250. if (fFirstTime)
  251. {
  252. // this should happen only if IE is created on a different
  253. // thread, such as OE dochost
  254. AddFirstBrowserToList(psb);
  255. }
  256. else
  257. {
  258. #endif
  259. lpThreadWindowInfo->cWindowCount++;
  260. // tack new window on end of list
  261. CShellBrowser2** rgpsb = (CShellBrowser2**)
  262. LocalReAlloc(lpThreadWindowInfo->rgpsb,
  263. lpThreadWindowInfo->cWindowCount * sizeof(CShellBrowser2 *), LMEM_MOVEABLE);
  264. ASSERT(rgpsb);
  265. if (rgpsb)
  266. {
  267. lpThreadWindowInfo->rgpsb = rgpsb;
  268. rgpsb[lpThreadWindowInfo->cWindowCount-1] = psb;
  269. psb->AddRef();
  270. }
  271. #ifdef NO_MARSHALLING
  272. }
  273. #endif
  274. // The message pump would go here.
  275. // Let the threadproc handle it.
  276. psb->Release();
  277. }
  278. }
  279. else
  280. {
  281. // Unregister any pending that may be there
  282. WinList_Revoke(piei->dwRegister);
  283. TraceMsg(DM_ERROR, "IEFrameNewWindowSameThread CreateWindow failed");
  284. }
  285. Done:
  286. if (pszCloseEvent)
  287. {
  288. FireEventSz(pszCloseEvent);
  289. }
  290. if (piei)
  291. delete piei;
  292. }
  293. EXTERN_C THREADWINDOWINFO * InitializeThreadInfoStructs()
  294. {
  295. THREADWINDOWINFO *lpThreadWindowInfo;
  296. // Allocate a TLS if needed. Will be freed in the WEP.
  297. if (~0 == g_TLSThreadWindowInfo)
  298. {
  299. g_TLSThreadWindowInfo = TlsAlloc();
  300. ASSERT (~0 != g_TLSThreadWindowInfo);
  301. lpThreadWindowInfo = NULL;
  302. }
  303. else
  304. {
  305. lpThreadWindowInfo = (THREADWINDOWINFO *) TlsGetValue(g_TLSThreadWindowInfo);
  306. }
  307. if (NULL == lpThreadWindowInfo && ~0 != g_TLSThreadWindowInfo)
  308. {
  309. lpThreadWindowInfo = (THREADWINDOWINFO *) LocalAlloc(LPTR, sizeof(*lpThreadWindowInfo));
  310. TlsSetValue(g_TLSThreadWindowInfo, lpThreadWindowInfo);
  311. }
  312. ASSERT(lpThreadWindowInfo);
  313. return lpThreadWindowInfo;
  314. }
  315. EXTERN_C void FreeThreadInfoStructs()
  316. {
  317. THREADWINDOWINFO *lpThreadWindowInfo;
  318. lpThreadWindowInfo = (THREADWINDOWINFO *)TlsGetValue(g_TLSThreadWindowInfo);
  319. if( lpThreadWindowInfo )
  320. {
  321. LocalFree(lpThreadWindowInfo->rgpsb);
  322. LocalFree(lpThreadWindowInfo);
  323. TlsSetValue(g_TLSThreadWindowInfo, NULL);
  324. }
  325. }
  326. EXTERN_C void AddFirstBrowserToList( CShellBrowser2 *psb )
  327. {
  328. if( psb )
  329. {
  330. THREADWINDOWINFO *lpThreadWindowInfo;
  331. lpThreadWindowInfo = (THREADWINDOWINFO *) TlsGetValue(g_TLSThreadWindowInfo);
  332. lpThreadWindowInfo->cWindowCount++;
  333. // tack new window on end of list
  334. lpThreadWindowInfo->rgpsb = (CShellBrowser2**) LocalAlloc(LPTR, sizeof(CShellBrowser2 *));
  335. ASSERT(lpThreadWindowInfo->rgpsb); // if this fails we're DEAD
  336. if( lpThreadWindowInfo->rgpsb )
  337. {
  338. lpThreadWindowInfo->rgpsb[0] = psb;
  339. psb->AddRef();
  340. }
  341. }
  342. }
  343. EXTERN_C void RemoveBrowserFromList( CShellBrowser2 *psb )
  344. {
  345. if (psb->_fReallyClosed)
  346. {
  347. int i;
  348. BOOL fFoundSB = FALSE;
  349. THREADWINDOWINFO *lpThreadWindowInfo;
  350. lpThreadWindowInfo = (THREADWINDOWINFO *) TlsGetValue(g_TLSThreadWindowInfo);
  351. // remove the window from the list.
  352. ASSERT(psb->_pbbd->_hwnd == NULL);
  353. for (i = 0; i < lpThreadWindowInfo->cWindowCount; i++)
  354. {
  355. if( psb == lpThreadWindowInfo->rgpsb[i] )
  356. {
  357. fFoundSB = TRUE;
  358. break;
  359. }
  360. }
  361. if ( fFoundSB )
  362. {
  363. memmove(&lpThreadWindowInfo->rgpsb[i],
  364. &lpThreadWindowInfo->rgpsb[i+1],
  365. (--lpThreadWindowInfo->cWindowCount - i) * sizeof(psb));
  366. psb->Release();
  367. }
  368. }
  369. }
  370. #endif // NO_MARSHALLING
  371. #endif // UNIX