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.

624 lines
17 KiB

  1. /*****************************************************************************
  2. *
  3. * fnd.h - Main private header file
  4. *
  5. *****************************************************************************/
  6. /*****************************************************************************
  7. *
  8. * Coding conventions:
  9. *
  10. * + Follow standard shell coding conventions.
  11. *
  12. * + Standard K&R brace placement and indentation style.
  13. *
  14. * + Indent by 4 spaces.
  15. *
  16. * + Fully-brace all dependent clauses. Never write "if (c) foo();"
  17. *
  18. * + Do not return in the middle of a function. If forced,
  19. * use a "goto exit". This way, you can stick entry/exit stuff
  20. * later without getting caught out. (I learned this rule the
  21. * hard way.)
  22. *
  23. * + Declare variables with narrowest possible scope.
  24. *
  25. * + Always test for success, not failure! The compiler will
  26. * thank you.
  27. *
  28. *****************************************************************************/
  29. /*****************************************************************************
  30. *
  31. * NOTE! This code was written for readability, not efficiency.
  32. *
  33. * I'm trusting the compiler to do optimizations like these:
  34. *
  35. * "Parameter alias":
  36. *
  37. * Function(LPFOO pfoo)
  38. * {
  39. * LPBAR pbar = (LPBAR)pfoo;
  40. * ... use pbar and never mention pfoo again ...
  41. * }
  42. *
  43. * --> becomes
  44. *
  45. * Function(LPFOO pfoo)
  46. * {
  47. * #define pbar ((LPBAR)pfoo)
  48. * ... use pbar and never mention pfoo again ...
  49. * #undef pbar
  50. * }
  51. *
  52. * "Speculative Execution":
  53. *
  54. * Function(PFOO pfoo)
  55. * {
  56. * BOOL fRc;
  57. * if (... condition 1 ...) {
  58. * ... complicated stuff ...
  59. * *pfoo = result;
  60. * fRc = 1;
  61. * } else { // condition 1 failed
  62. * *pfoo = 0;
  63. * fRc = 0;
  64. * }
  65. * return fRc;
  66. * }
  67. *
  68. * --> becomes
  69. *
  70. * Function(PFOO pfoo)
  71. * {
  72. * BOOL fRc = 0;
  73. * *pfoo = 0;
  74. * if (... condition 1 ...) {
  75. * ... complicated stuff ...
  76. * *pfoo = result;
  77. * fRc = 1;
  78. * }
  79. * return fRc;
  80. * }
  81. *
  82. * "Single Exit":
  83. *
  84. * Function(...)
  85. * {
  86. * BOOL fRc;
  87. * if (... condition 1 ...) {
  88. * ...
  89. * if (... condition 2 ...) {
  90. * ...
  91. * fRc = 1;
  92. * } else { // condition 2 failed
  93. * ... clean up ...
  94. * fRc = 0;
  95. * }
  96. * } else { // condition 1 failed
  97. * ... clean up ...
  98. * fRc = 0;
  99. * }
  100. * return fRc;
  101. * }
  102. *
  103. * --> becomes
  104. *
  105. * Function(...)
  106. * {
  107. * if (... condition 1 ...) {
  108. * ...
  109. * if (... condition 2 ...) {
  110. * ...
  111. * return 1;
  112. * } else { // condition 2 failed
  113. * ... clean up ...
  114. * return 0;
  115. * }
  116. * } else { // condition 1 failed
  117. * ... clean up ...
  118. * return 0;
  119. * }
  120. * NOTREACHED;
  121. * }
  122. *
  123. *
  124. *
  125. *****************************************************************************/
  126. #define WIN32_LEAN_AND_MEAN
  127. #define NOIME
  128. #define NOSERVICE
  129. #define _WIN32_WINDOWS 0x0400
  130. #include <windows.h>
  131. #ifdef RC_INVOKED /* Define some tags to speed up rc.exe */
  132. #define __RPCNDR_H__ /* Don't need RPC network data representation */
  133. #define __RPC_H__ /* Don't need RPC */
  134. #include <oleidl.h> /* Get the DROPEFFECT stuff */
  135. #define _OLE2_H_ /* But none of the rest */
  136. #define _WINDEF_
  137. #define _WINBASE_
  138. #define _WINGDI_
  139. #define NONLS
  140. #define _WINCON_
  141. #define _WINREG_
  142. #define _WINNETWK_
  143. #define _INC_COMMCTRL
  144. #define _INC_SHELLAPI
  145. #else
  146. #include <windowsx.h>
  147. #endif
  148. #include <shlobj.h>
  149. #include <shellapi.h>
  150. #include <objbase.h>
  151. #include "resrc2.h"
  152. #define _IOffset(class, itf) ((UINT_PTR)&(((class *)0)->itf))
  153. #define IToClass(class, itf, pitf) ((class *)(((LPSTR)pitf)-_IOffset(class, itf)))
  154. #ifndef RC_INVOKED
  155. #ifdef _WIN64
  156. #pragma pack(push,8)
  157. #endif // _WIN64
  158. /*****************************************************************************
  159. *
  160. * Stuff I'm tired of typing over and over.
  161. *
  162. *****************************************************************************/
  163. typedef LPITEMIDLIST PIDL, *PPIDL;
  164. typedef LPCITEMIDLIST PCIDL;
  165. typedef LPSHELLFOLDER PSF;
  166. typedef LPVOID PV;
  167. typedef LPVOID *PPV;
  168. typedef LPCVOID PCV;
  169. typedef REFIID RIID;
  170. typedef LPUNKNOWN PUNK;
  171. /*****************************************************************************
  172. *
  173. * Baggage - Stuff I carry everywhere
  174. *
  175. *****************************************************************************/
  176. #define INTERNAL NTAPI /* Called only within a translation unit */
  177. #define EXTERNAL NTAPI /* Called from other translation units */
  178. #define INLINE static __inline
  179. #define BEGIN_CONST_DATA data_seg(".text", "CODE")
  180. #define END_CONST_DATA data_seg(".data", "DATA")
  181. #define OBJAT(T, v) (*(T *)(v)) /* Pointer punning */
  182. #define PUN(T, v) OBJAT(T, &(v)) /* General-purpose type-punning */
  183. /*
  184. * Convert a count of TCHAR's to a count of bytes.
  185. */
  186. #define cbCtch(ctch) ((ctch) * sizeof(TCHAR))
  187. /*
  188. * Convert an object (X) to a count of bytes (cb).
  189. */
  190. /*
  191. * Convert an array name (A) to a generic count (c).
  192. */
  193. #define cA(a) (cbX(a)/cbX(a[0]))
  194. /*
  195. * Convert an array name (A) to a pointer to its Max.
  196. * (I.e., one past the last element.)
  197. */
  198. #define pvMaxA(a) (&a[cA(a)])
  199. #ifdef _WIN64
  200. #define ALIGNTYPE LARGE_INTEGER
  201. #define ALIGN ((ULONG) (sizeof(ALIGNTYPE) - 1))
  202. #define LcbAlignLcb(lcb) (((lcb) + ALIGN) & ~ALIGN)
  203. #endif
  204. #ifdef _WIN64
  205. #define pvSubPvCb(pv, cb) ((PV)((PBYTE)pv - LcbAlignLcb((cb))))
  206. #define pvAddPvCb(pv, cb) ((PV)((PBYTE)pv + LcbAlignLcb((cb))))
  207. #define cbSubPvPv(p1, p2) ((PBYTE)(p1) - (PBYTE)(p2))
  208. #else
  209. #define pvSubPvCb(pv, cb) ((PV)((PBYTE)pv - (cb)))
  210. #define pvAddPvCb(pv, cb) ((PV)((PBYTE)pv + (cb)))
  211. #define cbSubPvPv(p1, p2) ((PBYTE)(p1) - (PBYTE)(p2))
  212. #endif //WIN64
  213. /*
  214. * Round cb up to the nearest multiple of cbAlign. cbAlign must be
  215. * a power of 2 whose evaluation entails no side-effects.
  216. */
  217. #define ROUNDUP(cb, cbAlign) ((((cb) + (cbAlign) - 1) / (cbAlign)) * (cbAlign))
  218. #define cbX(X) sizeof(X)
  219. /*
  220. * lfNeVV
  221. *
  222. * Given two values, return zero if they are equal and nonzero if they
  223. * are different. This is the same as (v1) != (v2), except that the
  224. * return value on unequal is a random nonzero value instead of 1.
  225. * (lf = logical flag)
  226. *
  227. * lfNePvPv
  228. *
  229. * The same as lfNeVV, but for pointers.
  230. *
  231. * lfPv
  232. *
  233. * Nonzero if pv is not null.
  234. *
  235. */
  236. #define lfNeVV(v1, v2) ((v1) - (v2))
  237. #define lfNePvPv(v1, v2) lfNeVV((DWORD)(PV)(v1), (DWORD)(PV)(v2))
  238. #define lfPv(pv) ((BOOL)(PV)(pv))
  239. /*
  240. * land -- Logical and. Evaluate the first. If the first is zero,
  241. * then return zero. Otherwise, return the second.
  242. */
  243. #define fLandFF(f1, f2) ((f1) ? (f2) : 0)
  244. /*
  245. * lor -- Logical or. Evaluate the first. If the first is nonzero,
  246. * return it. Otherwise, return the second.
  247. *
  248. * Unfortunately, due to the C language, this can't
  249. * be implemented, so we just return 1 if the first is nonzero.
  250. * GNU has an extension that supports this, which we use. //;Internal
  251. */
  252. #if defined(__GNUC__) //;Internal
  253. #define fLorFF(f1, f2) ((f1) ?: (f2)) //;Internal
  254. #else //;Internal
  255. #define fLorFF(f1, f2) ((f1) ? 1 : (f2))
  256. #endif //;Internal
  257. /*
  258. * limp - logical implication. True unless the first is nonzero and
  259. * the second is zero.
  260. */
  261. #define fLimpFF(f1, f2) (!(f1) || (f2))
  262. /*
  263. * leqv - logical equivalence. True if both are zero or both are nonzero.
  264. */
  265. #define fLeqvFF(f1, f2) (!(f1) == !(f2))
  266. /*
  267. * InOrder - checks that i1 <= i2 < i3.
  268. */
  269. #define fInOrder(i1, i2, i3) ((unsigned)((i2)-(i1)) < (unsigned)((i3)-(i1)))
  270. /*
  271. * memeq - Reverse of memcmp
  272. */
  273. #define memeq !memcmp
  274. /*
  275. * fPvPfnCmpPv - Compare two objects for equality using the comparison
  276. * function and the desired outcome. E.g.,
  277. *
  278. * fPvPfnCmpPv(psz1, lstrcmpi, >, psz2)
  279. *
  280. * returns nonzero if psz1 is greater than psz2 according
  281. * to lstrcmpi.
  282. */
  283. #define fPvPfnCmpPv(p1, pfn, cmp, p2) (pfn(p1, p2) cmp 0)
  284. /*
  285. * lstreq - nonzero if two strings (according to lstrcmp) are equal
  286. * lstrne - nonzero if two strings (according to lstrcmp) are different
  287. *
  288. * lstrieq - nonzero if two strings (according to lstrcmpi) are equal
  289. * lstrine - nonzero if two strings (according to lstrcmpi) are different
  290. *
  291. * lstrieqA - nonzero if two strings (according to lstrcmpiA) are equal
  292. * lstrineA - nonzero if two strings (according to lstrcmpiA) are different
  293. */
  294. #define lstreq !lstrcmp
  295. #define lstrne lstrcmp
  296. #define lstrieq !lstrcmpi
  297. #define lstrine lstrcmpi
  298. #define lstrieqA !lstrcmpiA
  299. #define lstrineA lstrcmpiA
  300. /*****************************************************************************
  301. *
  302. * Wrappers and other quickies
  303. *
  304. *****************************************************************************/
  305. #define pvExchangePpvPv(ppv, pv) \
  306. (PV)InterlockedExchangePointer((ppv), (pv))
  307. #define hresUs(us) MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(us))
  308. #define hresLe(le) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, (USHORT)(le))
  309. /*****************************************************************************
  310. *
  311. * Static globals: Initialized at PROCESS_ATTACH and never modified.
  312. *
  313. *****************************************************************************/
  314. HINSTANCE g_hinst; /* My resource instance handle */
  315. HINSTANCE g_hinstApp; /* My instance handle */
  316. HINSTANCE g_hinstWABDLL; /* My WAB32.DLL instance handle */
  317. //DEFINE_GUID(CLSID_Fnd, 0x37865980, 0x75d1, 0x11cf,
  318. // 0xbf,0xc7,0x44,0x45,0x53,0x54,0,0);
  319. // {32714800-2E5F-11d0-8B85-00AA0044F941}
  320. DEFINE_GUID(CLSID_Fnd,
  321. 0x32714800, 0x2e5f, 0x11d0, 0x8b, 0x85, 0x0, 0xaa, 0x0, 0x44, 0xf9, 0x41);
  322. /*****************************************************************************
  323. *
  324. * Dynamic Globals. There should be as few of these as possible.
  325. *
  326. * All access to dynamic globals must be thread-safe.
  327. *
  328. *****************************************************************************/
  329. ULONG g_cRef; /* Global reference count */
  330. /*****************************************************************************
  331. *
  332. * fndcf.c - Class Factory
  333. *
  334. *****************************************************************************/
  335. STDMETHODIMP CFndFactory_New(RIID riid, PPV ppvObj);
  336. /*****************************************************************************
  337. *
  338. * fndcm.c - IContextMenu, IShellExtInit
  339. *
  340. *****************************************************************************/
  341. STDMETHODIMP CFndCm_New(RIID riid, PPV ppvObj);
  342. /*****************************************************************************
  343. *
  344. * Common object managers.
  345. *
  346. *****************************************************************************/
  347. typedef struct PREVTBL0 { /* Simple (non-OLE) object */
  348. void (NTAPI *FinalizeProc)(PV pv); /* Finalization procedure */
  349. } PREVTBL0, *PPREVTBL0;
  350. typedef struct PREVTBL { /* Primary interface */
  351. REFIID riid; /* Type of this object */
  352. void (NTAPI *FinalizeProc)(PV pv); /* Finalization procedure */
  353. } PREVTBL, *PPREVTBL;
  354. typedef struct PREVTBL2 { /* Secondary interface */
  355. ULONG lib; /* offset from start of object */
  356. } PREVTBL2, *PPREVTBL2;
  357. #define Simple_Interface(C) Primary_Interface(C, IUnknown)
  358. #define Simple_Vtbl(C) Primary_Vtbl(C)
  359. #define Simple_Interface_Begin(C) \
  360. struct S_##C##Vtbl c_####C##VI = { { \
  361. &IID_##IUnknown, \
  362. C##_Finalize, \
  363. }, { \
  364. Common##_QueryInterface, \
  365. Common##_AddRef, \
  366. Common##_Release, \
  367. #define Simple_Interface_End(C) Primary_Interface_End(C, IUnknown)
  368. #define Primary_Interface(C, I) \
  369. extern struct S_##C##Vtbl { \
  370. PREVTBL prevtbl; \
  371. I##Vtbl vtbl; \
  372. } c_##C##VI \
  373. #define Primary_Vtbl(C) &c_##C##VI.vtbl
  374. #define Primary_Interface_Begin(C, I) \
  375. struct S_##C##Vtbl c_####C##VI = { { \
  376. &IID_##I, \
  377. C##_Finalize, \
  378. }, { \
  379. C##_QueryInterface, \
  380. C##_AddRef, \
  381. C##_Release, \
  382. #define Primary_Interface_End(C, I) \
  383. } }; \
  384. #define Secondary_Interface(C, I) \
  385. extern struct S_##I##_##C##Vtbl { \
  386. PREVTBL2 prevtbl; \
  387. I##Vtbl vtbl; \
  388. } c_##I##_##C##VI \
  389. #define Secondary_Vtbl(C, I) &c_##I##_##C##VI.vtbl
  390. #define Secondary_Interface_Begin(C, I, nm) \
  391. struct S_##I##_##C##Vtbl c_##I##_##C##VI = { { \
  392. _IOffset(C, nm), \
  393. }, { \
  394. Forward_QueryInterface, \
  395. Forward_AddRef, \
  396. Forward_Release, \
  397. #define Secondary_Interface_End(C, I, nm) \
  398. } }; \
  399. #ifdef _WIN64
  400. #pragma pack(pop)
  401. #endif //_WIN64
  402. STDMETHODIMP Common_QueryInterface(PV, REFIID, PPV);
  403. STDMETHODIMP_(ULONG) _Common_AddRef(PV pv);
  404. STDMETHODIMP_(ULONG) _Common_Release(PV pv);
  405. #define Common_AddRef _Common_AddRef
  406. #define Common_Release _Common_Release
  407. void EXTERNAL Common_Finalize(PV);
  408. STDMETHODIMP _Common_New(ULONG cb, PV vtbl, PPV ppvObj);
  409. #define Common_NewCb(cb, C, ppvObj) _Common_New(cb, Primary_Vtbl(C), ppvObj)
  410. #define Common_New(C, ppvObj) Common_NewCb(cbX(C), C, ppvObj)
  411. STDMETHODIMP Forward_QueryInterface(PV pv, REFIID riid, PPV ppvObj);
  412. STDMETHODIMP_(ULONG) Forward_AddRef(PV pv);
  413. STDMETHODIMP_(ULONG) Forward_Release(PV pv);
  414. /*****************************************************************************
  415. *
  416. * Common_CopyAddRef
  417. *
  418. * Copy a pointer and increment its reference count.
  419. *
  420. * Cannot be a macro because Common_AddRef evaluates its argument
  421. * twice.
  422. *
  423. *****************************************************************************/
  424. INLINE void Common_CopyAddRef(PV pvDst, PV pvSrc)
  425. {
  426. PPV ppvDst = pvDst;
  427. *ppvDst = pvSrc;
  428. Common_AddRef(pvSrc);
  429. }
  430. /*****************************************************************************
  431. *
  432. * Invoking OLE methods.
  433. *
  434. * Invoke_Release is called with a pointer to the object, not with
  435. * the object itself. It zeros out the variable on the release.
  436. *
  437. *****************************************************************************/
  438. void EXTERNAL Invoke_AddRef(PV pv);
  439. void EXTERNAL Invoke_Release(PV pv);
  440. /*****************************************************************************
  441. *
  442. * assert.c - Assertion stuff
  443. *
  444. *****************************************************************************/
  445. typedef enum {
  446. sqflAlways = 0x00000000, /* Unconditional */
  447. sqflDll = 0x00000001, /* Dll bookkeeping */
  448. sqflFactory = 0x00000002, /* IClassFactory */
  449. sqflCm = 0x00000004, /* IContextMenu */
  450. sqflCommon = 0x00000000, /* common.c */
  451. sqflError = 0x80000000, /* Errors */
  452. } SQFL; /* squiffle */
  453. void EXTERNAL SquirtSqflPtszV(SQFL sqfl, LPCTSTR ptsz, ...);
  454. int EXTERNAL AssertPtszPtszLn(LPCTSTR ptszExpr, LPCTSTR ptszFile, int iLine);
  455. /*****************************************************************************
  456. *
  457. * Procedure enter/exit tracking.
  458. *
  459. * Start a procedure with
  460. *
  461. * EnterProc(ProcedureName, (_ "format", arg, arg, arg, ...));
  462. *
  463. * The format string is documented in EmitPal.
  464. *
  465. * End a procedure with one of the following:
  466. *
  467. * ExitProc();
  468. *
  469. * Procedure returns no value.
  470. *
  471. * ExitProcX();
  472. *
  473. * Procedure returns an arbitrary DWORD.
  474. *
  475. * ExitOleProc();
  476. *
  477. * Procedure returns an HRESULT (named "hres").
  478. *
  479. * ExitOleProcPpv(ppvOut);
  480. *
  481. * Procedure returns an HRESULT (named "hres") and, on success,
  482. * puts a new object in ppvOut.
  483. *
  484. *****************************************************************************/
  485. #define cpvArgMax 10 /* Max of 10 args per procedure */
  486. #ifdef _WIN64
  487. #pragma pack(push,8)
  488. #endif // _WIN64
  489. typedef struct ARGLIST {
  490. LPCSTR pszProc;
  491. LPCSTR pszFormat;
  492. PV rgpv[cpvArgMax];
  493. } ARGLIST, *PARGLIST;
  494. void EXTERNAL ArgsPalPszV(PARGLIST pal, LPCSTR psz, ...);
  495. void EXTERNAL EnterSqflPszPal(SQFL sqfl, LPCTSTR psz, PARGLIST pal);
  496. void EXTERNAL ExitSqflPalHresPpv(SQFL, PARGLIST, HRESULT, PPV);
  497. #define AssertFPtsz(c, ptsz)
  498. #define ValidateF(c) (c)
  499. #define D(x)
  500. #define SetupEnterProc(nm)
  501. #define DoEnterProc(v)
  502. #define EnterProc(nm, v)
  503. #define ExitOleProcPpv(ppv)
  504. #define ExitOleProc()
  505. #define ExitProc()
  506. #define AssertF(c) AssertFPtsz(c, TEXT(#c))
  507. /*****************************************************************************
  508. *
  509. * Macros that forward to the common handlers after squirting.
  510. * Use these only in DEBUG.
  511. *
  512. * It is assumed that sqfl has been #define'd to the appropriate sqfl.
  513. *
  514. *****************************************************************************/
  515. /*****************************************************************************
  516. *
  517. * mem.c
  518. *
  519. * Be extremely careful with FreePv, because it doesn't work if
  520. * the pointer is null.
  521. *
  522. *****************************************************************************/
  523. STDMETHODIMP EXTERNAL ReallocCbPpv(UINT cb, PV ppvObj);
  524. STDMETHODIMP EXTERNAL AllocCbPpv(UINT cb, PV ppvObj);
  525. #define FreePpv(ppv) ReallocCbPpv(0, ppv)
  526. #define FreePv(pv) LocalFree((HLOCAL)(pv))
  527. #ifdef _WIN64
  528. #pragma pack(pop)
  529. #endif //_WIN64
  530. #endif /* !RC_INVOKED */