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.

611 lines
18 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992
  5. //
  6. // File: dfmsp.hxx
  7. //
  8. // Contents: DocFile and MultiStream shared private definitions
  9. //
  10. // History: 01-Apr-92 DrewB Created
  11. // 06-Sep-95 MikeHill Added P_NOSCRATCH
  12. //
  13. //---------------------------------------------------------------
  14. #ifndef __DFMSP_HXX__
  15. #define __DFMSP_HXX__
  16. #include <debnot.h>
  17. #include <wchar.h>
  18. #include <valid.h>
  19. // after props is cleaned, remove the no_deprecate define
  20. #define STRSAFE_NO_DEPRECATE
  21. #include <strsafe.h>
  22. #if !defined(MULTIHEAP) && !defined(_CHICAGO_)
  23. #define MULTIHEAP
  24. #include <tls.h>
  25. #endif
  26. #ifdef ASYNC
  27. #include <async.hxx>
  28. #endif
  29. //Enable large docfiles (>4GB files and larger sector sizes)
  30. #define LARGE_DOCFILE
  31. #define LARGE_STREAMS
  32. // Target-dependent things
  33. //
  34. // x86 16-bit build optimizations
  35. //
  36. // Some function parameters are always stack based pointers,
  37. // so we can let the compiler use near addressing via ss by
  38. // declaring the parameter stack based.
  39. //
  40. #if defined(_M_I286)
  41. #define STACKBASED __based(__segname("_STACK"))
  42. #else
  43. #define STACKBASED
  44. #endif
  45. //
  46. // x86 16-bit retail build optimizations
  47. //
  48. // For the retail build, we group the code segments,
  49. // allowing us to make many calls near.
  50. //
  51. #if defined(_M_I286) && DBG == 0 && defined(USE_NEAR)
  52. #define DFBASED
  53. #define DIR_CLASS __near
  54. #define FAT_CLASS __near
  55. #define MSTREAM_CLASS __near
  56. #define VECT_CLASS __near
  57. #else
  58. #define DFBASED
  59. #define DIR_CLASS
  60. #define FAT_CLASS
  61. #define MSTREAM_CLASS
  62. #define VECT_CLASS
  63. #endif
  64. // Compiler pragma define
  65. // Currently defined for C7 and C8
  66. // Unused as of 1/18/93
  67. #if ((_MSC_VER == 700) || (_MSC_VER == 800))
  68. #define MS_COMPILER
  69. #endif
  70. // Segmented memory model definitions
  71. #if !defined(HUGEP)
  72. #if defined(_M_I286)
  73. #define HUGEP __huge
  74. #else
  75. #define HUGEP
  76. #endif
  77. #endif
  78. #ifndef LISet32
  79. #define LISet32(li, v) ((li).QuadPart = (LONGLONG) (v))
  80. #endif
  81. #ifndef ULISet32
  82. #define ULISet32(li, v) ((li).QuadPart = (ULONGLONG) (v))
  83. #endif
  84. #define LISetLow(li, v) ((li).LowPart = (v))
  85. #define LISetHigh(li, v) ((li).HighPart = (v))
  86. #define ULISetLow(li, v) ((li).LowPart = (v))
  87. #define ULISetHigh(li, v) ((li).HighPart = (v))
  88. #define LIGetLow(li) ((li).LowPart)
  89. #define LIGetHigh(li) ((li).HighPart)
  90. #define ULIGetLow(li) ((li).LowPart)
  91. #define ULIGetHigh(li) ((li).HighPart)
  92. // Fast safe increment/decrement
  93. #if !defined(REF) && defined(USEATOMICINC)
  94. // Win32 specific functions
  95. // Should use #ifdef WIN32 instead of FLAT, but there isn't a WIN32
  96. #define AtomicInc(lp) InterlockedIncrement(lp)
  97. #define AtomicDec(lp) InterlockedDecrement(lp)
  98. #else
  99. #define AtomicInc(lp) (++*(lp))
  100. #define AtomicDec(lp) (--*(lp))
  101. #endif //!REF
  102. // Switchable ANSI/Unicode support for TCHAR
  103. // Conversion routines assume null termination before max characters
  104. #ifdef UNICODE
  105. #define ATOT(a, t, max) mbstowcs(t, a, max)
  106. #define TTOA(t, a, max) wcstombs(a, t, max)
  107. #define WTOT(w, t, max) StringCchCopyW (t, max, w)
  108. #define TTOW(t, w, max) StringCchCopyW (w, max, t)
  109. #define TSTR(s) L##s
  110. // printf format string
  111. #define TFMT "%ws"
  112. #else
  113. #define ATOT(a, t, max) StringCchCopyA (t, max, a)
  114. #define TTOA(t, a, max) StringCchCopyA (a, max, t)
  115. #define WTOT(w, t, max) wcstombs(t, w, max)
  116. #define TTOW(t, w, max) mbstowcs(w, t, max)
  117. #define TSTR(s) s
  118. // printf format string
  119. #define TFMT "%s"
  120. #endif
  121. // Switchable ANSI/Unicode support for OLECHAR
  122. // Conversion routines assume null termination before max characters
  123. #define OLEWIDECHAR
  124. #ifndef OLECHAR
  125. #define LPOLESTR LPWSTR
  126. #define LPCOLESTR LPCWSTR
  127. #define OLECHAR WCHAR
  128. #define OLESTR(str) L##str
  129. #endif //OLECHAR
  130. #define _OLESTDMETHODIMP STDMETHODIMP
  131. #define _OLEAPIDECL STDAPI
  132. #define _OLERETURN(sc) ResultFromScode(sc)
  133. #define _OLEAPI(name) name
  134. #define ATOOLE(a, t, max) mbstowcs(t, a, max)
  135. #define OLETOA(t, a, max) wcstombs(a, t, max)
  136. #define WTOOLE(w, t, max) StringCchCopyW(t, max, w)
  137. #define OLETOW(t, w, max) StringCchCopyW(w, max, t)
  138. #define olecscpy(t, f) lstrcpyW(t, f)
  139. #define olecslen(t) lstrlenW(t)
  140. #define OLESTR(s) L##s
  141. // printf format string
  142. #define OLEFMT "%ws"
  143. #ifdef _CAIRO_
  144. typedef LPSECURITY_ATTRIBUTES LPSTGSECURITY;
  145. #else
  146. typedef DWORD LPSTGSECURITY;
  147. #endif
  148. #ifdef _CAIRO_
  149. #define STATSTG_dwStgFmt dwStgFmt
  150. #else
  151. #define STATSTG_dwStgFmt reserved
  152. #endif
  153. // For NT 1.0a OLE we need to use based pointers for shared memory objects
  154. // since they might not be mapped at the same address in every process
  155. #if WIN32 == 100 || WIN32 > 200
  156. #define USEBASED
  157. #endif
  158. //We need DfInitSharedMemBase even if we aren't using based pointers,
  159. // since it sets up the shared mem allocator if one hasn't already
  160. // been set up.
  161. void DfInitSharedMemBase(void);
  162. #ifdef USEBASED
  163. #ifdef MULTIHEAP
  164. #define DFBASEPTR pvDfSharedMemBase()
  165. // The previous declaration of DFBASEPTR was:
  166. // extern __declspec(thread) void *DFBASEPTR;
  167. // Now, it is an inline function that returns the threadlocal base pointer
  168. // Reference to pointer syntax is needed for assignments to DFBASEPTR
  169. __forceinline void *& DFBASEPTR
  170. {
  171. COleTls otls;
  172. return otls->pvThreadBase;
  173. }
  174. #else
  175. #define DFBASEPTR pvDfSharedMemBase
  176. extern void *DFBASEPTR;
  177. #endif // MULTIHEAP
  178. #pragma warning(error: 4795 4796)
  179. #pragma warning(disable:4714)
  180. #undef DFBASED
  181. #ifdef MULTIHEAP
  182. // based pointers are replaced by CSafeBased... smart pointer macros
  183. // macros invoke conversion constructor and conversion operators
  184. //#define DFBASED __based(DFBASEDPTR)
  185. #define P_TO_BP(t, p) ((t)(p))
  186. #define BP_TO_P(t, bp) ((t)(bp))
  187. #else // MULTIHEAP
  188. #define DFBASED __based(DFBASEPTR)
  189. #define P_TO_BP(t, p) ((t)((p) ? (int)(t)(char *)(p) : 0))
  190. #define BP_TO_P(t, bp) (t)((bp) != 0 ? (bp) : 0)
  191. #endif // MULTIHEAP
  192. #else
  193. #define P_TO_BP(t, p) p
  194. #define BP_TO_P(t, bp) bp
  195. #endif //USEBASED
  196. //----------------------------------------------------------------------------
  197. // The name of this function might change, so encapsulate it
  198. #define DfGetScode(hr) GetScode(hr)
  199. // Buffer/pointer validation macros
  200. BOOL IsValidStgInterface (void * pv);
  201. #define AssertMsg(s) _Win4Assert(__FILE__, __LINE__, s)
  202. // MAC - We use Windows functions if available
  203. #if (WIN32 == 100 || WIN32 >= 300)
  204. #define IsValidHugePtrIn(pv, n) (IsValidPtrIn(pv, n))
  205. #define IsValidHugePtrOut(pv, n) (IsValidPtrOut(pv, n))
  206. #else
  207. #define IsValidHugePtrIn(pv, n) 1
  208. #define IsValidHugePtrOut(pv, n) ((pv) != NULL)
  209. #endif
  210. #define ValidateBuffer(pv, n) \
  211. (((pv) == NULL || !IsValidPtrIn(pv, n)) ? STG_E_INVALIDPOINTER : S_OK)
  212. #define ValidatePtrBuffer(pv) \
  213. ValidateBuffer(pv, sizeof(void *))
  214. #define ValidateHugeBuffer(pv, n) \
  215. (((pv) == NULL || !IsValidHugePtrIn(pv, n)) ? STG_E_INVALIDPOINTER : S_OK)
  216. #define ValidateOutBuffer(pv, n) \
  217. (!IsValidPtrOut(pv, n) ? STG_E_INVALIDPOINTER : S_OK)
  218. #define ValidateOutPtrBuffer(pv) \
  219. ValidateOutBuffer(pv, sizeof(void *))
  220. #define ValidateHugeOutBuffer(pv, n) \
  221. (!IsValidHugePtrOut(pv, n) ? STG_E_INVALIDPOINTER : S_OK)
  222. #if DBG==1
  223. #define ValidateIid(riid) \
  224. (!IsValidIid(riid) ? STG_E_INVALIDPOINTER : S_OK)
  225. #else
  226. // killed this macro in retail build since it used to do no useful work
  227. // now we are faster. see comment for ValidateIid.
  228. #define ValidateIid(riid) S_OK
  229. #endif
  230. #define ValidateInterface(punk, riid) \
  231. (!IsValidStgInterface(punk) ? STG_E_INVALIDPOINTER : S_OK)
  232. #if defined(OLEWIDECHAR)
  233. SCODE ValidateNameW(LPCWSTR pwcsName, UINT cchMax);
  234. #else
  235. // For non-Unicode builds, we verify all names before converting them
  236. // to wide character names, so there's no need to recheck.
  237. # define ValidateNameW(pwcs, cchMax) \
  238. S_OK
  239. #endif
  240. // Enumeration for Get/SetTime
  241. enum WHICHTIME
  242. {
  243. WT_CREATION,
  244. WT_MODIFICATION,
  245. WT_ACCESS
  246. };
  247. // Time type
  248. typedef FILETIME TIME_T;
  249. // Signature for transactioning
  250. typedef DWORD DFSIGNATURE;
  251. #define DF_INVALIDSIGNATURE ((DFSIGNATURE)-1)
  252. // Convenience macros for signature creation
  253. #define LONGSIG(c1, c2, c3, c4) \
  254. (((ULONG) (BYTE) (c1)) | \
  255. (((ULONG) (BYTE) (c2)) << 8) | \
  256. (((ULONG) (BYTE) (c3)) << 16) | \
  257. (((ULONG) (BYTE) (c4)) << 24))
  258. #ifndef min
  259. #define min(a, b) ((a)<(b) ? (a) : (b))
  260. #endif
  261. #ifndef max
  262. #define max(a, b) ((a)>(b) ? (a) : (b))
  263. #endif
  264. SCODE DfGetTOD(TIME_T *ptm);
  265. // Shared signature validation routine
  266. SCODE CheckSignature(BYTE *pb);
  267. // Docfile locally unique identity
  268. // Every entry in a multistream has a LUID generated and stored for it
  269. typedef DWORD DFLUID;
  270. #define DF_NOLUID 0
  271. typedef SNB SNBW;
  272. typedef STATSTG STATSTGW;
  273. #define CBSTORAGENAME (CWCSTORAGENAME*sizeof(WCHAR))
  274. int dfwcsnicmp(const WCHAR *wcsa, const WCHAR *wcsb, size_t len);
  275. #include <dfname.hxx>
  276. // Fast, fixed space iterator structure
  277. struct SIterBuffer
  278. {
  279. CDfName dfnName;
  280. DWORD type;
  281. };
  282. //SID is a Stream Identifier
  283. #define SID DFSID
  284. typedef ULONG SID;
  285. // IsEntry entry information
  286. struct SEntryBuffer
  287. {
  288. DFLUID luid;
  289. DWORD dwType;
  290. SID sid;
  291. };
  292. // Destroy flags
  293. #define DESTROY_FROM_HANDLE 0
  294. #define DESTROY_FROM_ENTRY 1
  295. #define DESTROY_FROM 0x01
  296. #define DESTROY_SELF 0x40
  297. #define DESTROY_RECURSIVE 0x80
  298. #define DESTROY_HANDLE (DESTROY_FROM_HANDLE | DESTROY_SELF)
  299. #define DESTROY_ENTRY (DESTROY_FROM_ENTRY | DESTROY_SELF)
  300. // Root startup flags
  301. #define RSF_OPEN 0x00
  302. #define RSF_CONVERT 0x01
  303. #define RSF_TRUNCATE 0x02
  304. #define RSF_CREATE 0x04
  305. #define RSF_DELAY 0x08
  306. #define RSF_DELETEONRELEASE 0x10
  307. #define RSF_OPENCREATE 0x20
  308. #define RSF_SCRATCH 0x40
  309. #define RSF_SNAPSHOT 0x80
  310. #define RSF_NO_BUFFERING 0x200
  311. #define RSF_ENCRYPTED 0x400
  312. #define RSF_SECTORSIZE4K 0xC000
  313. #define RSF_SECTORSIZE8K 0xD000
  314. #define RSF_SECTORSIZE16K 0xE000
  315. #define RSF_SECTORSIZE32K 0xF000
  316. #define RSF_SECTORSIZE_MASK 0xF000
  317. // The sector size flags can be converted to sector shifts by >> 12 bits
  318. #define RSF_CREATEFLAGS (RSF_CREATE | RSF_TRUNCATE | RSF_OPENCREATE)
  319. #define RSF_TEMPFILE (RSF_SCRATCH | RSF_SNAPSHOT)
  320. // Stream copy buffer size
  321. ULONG const STREAMBUFFERSIZE = 8192;
  322. ULONG const LARGESTREAMBUFFERSIZE = 256*1024;
  323. // Docfile flags for permissions and other information kept
  324. // on streams and docfiles
  325. typedef DWORD DFLAGS;
  326. #define DF_TRANSACTEDSELF 0x0001
  327. #define DF_TRANSACTED 0x0002
  328. #define DF_DIRECT 0x0000
  329. #define DF_INDEPENDENT 0x0004
  330. #define DF_DEPENDENT 0x0000
  331. #define DF_COMMIT 0x0008
  332. #define DF_ABORT 0x0000
  333. #define DF_INVALID 0x0010
  334. #define DF_REVERTED 0x0020
  335. #define DF_NOTREVERTED 0x0000
  336. #define DF_READ 0x0040
  337. #define DF_WRITE 0x0080
  338. #define DF_READWRITE (DF_READ | DF_WRITE)
  339. #define DF_DENYREAD 0x0100
  340. #define DF_DENYWRITE 0x0200
  341. #define DF_DENYALL (DF_DENYREAD | DF_DENYWRITE)
  342. #define DF_PRIORITY 0x0400
  343. #define DF_CREATE 0x0800
  344. #define DF_CACHE 0x1000
  345. #define DF_NOUPDATE 0x2000
  346. #define DF_NOSCRATCH 0x4000
  347. #if WIN32 >= 300
  348. #define DF_ACCESSCONTROL 0x8000
  349. #endif
  350. #define DF_COORD 0x10000
  351. #define DF_COMMITTING 0x20000
  352. #define DF_NOSNAPSHOT 0x40000
  353. // docfile can be bigger than 4G
  354. #define DF_LARGE 0x80000
  355. // Shift required to translate from DF_READWRITE to DF_DENYALL
  356. #define DF_DENIALSHIFT 2
  357. // Permission abstraction macros
  358. // These only work with DF_* flags
  359. #define P_READ(f) ((f) & DF_READ)
  360. #define P_WRITE(f) ((f) & DF_WRITE)
  361. #define P_READWRITE(f) (((f) & (DF_READ | DF_WRITE)) == (DF_READ | DF_WRITE))
  362. #define P_DENYREAD(f) ((f) & DF_DENYREAD)
  363. #define P_DENYWRITE(f) ((f) & DF_DENYWRITE)
  364. #define P_DENYALL(f) (((f) & (DF_DENYREAD | DF_DENYWRITE)) == \
  365. (DF_DENYREAD | DF_DENYWRITE))
  366. #define P_PRIORITY(f) ((f) & DF_PRIORITY)
  367. #define P_TRANSACTED(f) ((f) & DF_TRANSACTED)
  368. #define P_DIRECT(f) (!P_TRANSACTED(f))
  369. #define P_INDEPENDENT(f) (((DFLAGS)f) & DF_INDEPENDENT)
  370. #define P_DEPENDENT(f) (!P_INDEPENDENT(f))
  371. #define P_TSELF(f) ((f) & DF_TRANSACTEDSELF)
  372. #define P_INVALID(f) ((f) & DF_INVALID)
  373. #define P_REVERTED(f) ((f) & DF_REVERTED)
  374. #define P_COMMIT(f) ((f) & DF_COMMIT)
  375. #define P_ABORT(f) (!P_COMMIT(f))
  376. #define P_CREATE(f) ((f) & DF_CREATE)
  377. #define P_CACHE(f) ((f) & DF_CACHE)
  378. #define P_NOUPDATE(f) ((f) & DF_NOUPDATE)
  379. #define P_COORD(f) ((f) & DF_COORD)
  380. #define P_COMMITTING(f) ((f) & DF_COMMITTING)
  381. #define P_NOSCRATCH(f) ((f) & DF_NOSCRATCH)
  382. #define P_NOSNAPSHOT(f) ((f) & DF_NOSNAPSHOT)
  383. // Translation functions
  384. DFLAGS ModeToDFlags(DWORD const dwModeFlags);
  385. DWORD DFlagsToMode(DFLAGS const df);
  386. // Flags for what state has been dirtied
  387. #define DIRTY_CREATETIME 0x0001
  388. #define DIRTY_MODIFYTIME 0x0002
  389. #define DIRTY_ACCESSTIME 0x0004
  390. #define DIRTY_CLASS 0x0008
  391. #define DIRTY_STATEBITS 0x0010
  392. // Allow text in asserts
  393. #define aMsg(s) ((char *)(s) != NULL)
  394. // Indicate that something is a property value
  395. // This must not conflict with official STGTY_* flags
  396. #define STGTY_REAL (STGTY_STORAGE | STGTY_STREAM | STGTY_LOCKBYTES)
  397. #define REAL_STGTY(f) (f)
  398. // Buffer management
  399. #ifdef LARGE_DOCFILE
  400. #define CB_LARGEBUFFER 65536
  401. #else
  402. #define CB_LARGEBUFFER 32768
  403. #endif
  404. #define CB_PAGEBUFFER 4096
  405. #define CB_SMALLBUFFER 512
  406. extern SCODE GetBuffer(ULONG cbMin, ULONG cbMax, BYTE **ppb,
  407. ULONG *pcbActual);
  408. extern void GetSafeBuffer(ULONG cbMin, ULONG cbMax, BYTE **ppb,
  409. ULONG *pcbActual);
  410. extern void FreeBuffer(BYTE *pb);
  411. #include <dfmem.hxx>
  412. #define DfAllocWC(cwc, ppwcs) (*ppwcs = (WCHAR *)\
  413. TaskMemAlloc((cwc)*sizeof(WCHAR)),\
  414. (*ppwcs != NULL) ? S_OK: STG_E_INSUFFICIENTMEMORY)
  415. #define DfAllocWCS(pwcs, ppwcs) DfAllocWC(lstrlenW(pwcs)+1, ppwcs)
  416. SCODE Win32ErrorToScode(DWORD dwErr);
  417. #define STG_SCODE(err) Win32ErrorToScode(err)
  418. #ifdef MULTIHEAP
  419. //+------------------------------------------------------------------------
  420. //
  421. // Macro: SAFE_DFBASED_PTR
  422. //
  423. // Purpose: Pointer to memory created by shared memory allocator.
  424. // This macro replaces the __based() compiler keyword
  425. // Only the offset is stored in _p, and conversion operators
  426. // return the absolute address (by adding the base address).
  427. // The smart pointer can only change through:
  428. // construction, assignment operator=
  429. // The smart pointer can be read through:
  430. // operator->, operator*, (casting to unbased type)
  431. // Destroying the smart pointer does not invoke _p's destructor
  432. //
  433. // Notes: There is special logic to translate a NULL based pointer
  434. // into a NULL absolute pointer, and vice versa.
  435. // We can do this without ambiguity since DFBASEPTR can
  436. // never be returned from CSmAlllocator::Alloc
  437. // (DFBASEPTR is really a CHeapHeader pointer, part of the heap)
  438. //
  439. // Arguments: [SpName] - class name of the smart based pointer
  440. // [SpType] - class name of the original unbased type
  441. //
  442. // History: 22-Feb-96 HenryLee Created
  443. //
  444. //-------------------------------------------------------------------------
  445. #define SAFE_DFBASED_PTR(SpName,SpType) \
  446. class SpName \
  447. { \
  448. public: \
  449. inline SpName () : _p(NULL) \
  450. { \
  451. } \
  452. inline SpName (SpType *p) \
  453. { \
  454. _p = (p) ? (ULONG_PTR)((BYTE*)p - (ULONG_PTR)DFBASEPTR) : NULL; \
  455. } \
  456. inline ~##SpName () \
  457. { \
  458. } \
  459. __forceinline SpType* operator-> () const \
  460. { \
  461. return (SpType *)(_p ? (BYTE *)_p + (ULONG_PTR)DFBASEPTR : NULL); \
  462. } \
  463. __forceinline SpType& operator * () const \
  464. { \
  465. return * (SpType *)(_p ? (BYTE *)_p + (ULONG_PTR)DFBASEPTR : NULL); \
  466. } \
  467. __forceinline operator SpType* () const \
  468. { \
  469. return (SpType *)(_p ? (BYTE *)_p + (ULONG_PTR)DFBASEPTR : NULL); \
  470. } \
  471. __forceinline SpType* operator= (SpType* p) \
  472. { \
  473. _p = (p) ? (ULONG_PTR)((BYTE*)p - (ULONG_PTR)DFBASEPTR) : NULL; \
  474. return p; \
  475. } \
  476. private: \
  477. ULONG_PTR _p; \
  478. }; \
  479. #else
  480. #define SAFE_DFBASED_PTR(SpName,SpType) \
  481. typedef SpType DFBASED * SpName;
  482. #endif // MULTIHEAP
  483. #include <widewrap.h>
  484. #ifndef STG_E_PENDINGCONTROL
  485. #define STG_E_PENDINGCONTROL _HRESULT_TYPEDEF_(0x80030204L)
  486. #endif
  487. #endif // #ifndef __DFMSP_HXX__