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.

499 lines
8.3 KiB

  1. /*
  2. * stub.c - Stub ADT module.
  3. */
  4. /* Headers
  5. **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. #include "stub.h"
  9. /* Macros
  10. *********/
  11. /* get a pointer to the stub type descriptor for a STUB */
  12. #define GetStubTypeDescriptor(pcs) (&(Mrgcstd[pcs->st]))
  13. /* Types
  14. ********/
  15. /* stub functions */
  16. typedef TWINRESULT (*UNLINKSTUBPROC)(PSTUB);
  17. typedef void (*DESTROYSTUBPROC)(PSTUB);
  18. typedef void (*LOCKSTUBPROC)(PSTUB);
  19. typedef void (*UNLOCKSTUBPROC)(PSTUB);
  20. /* stub type descriptor */
  21. typedef struct _stubtypedescriptor
  22. {
  23. UNLINKSTUBPROC UnlinkStub;
  24. DESTROYSTUBPROC DestroyStub;
  25. LOCKSTUBPROC LockStub;
  26. UNLOCKSTUBPROC UnlockStub;
  27. }
  28. STUBTYPEDESCRIPTOR;
  29. DECLARE_STANDARD_TYPES(STUBTYPEDESCRIPTOR);
  30. /* Module Prototypes
  31. ********************/
  32. PRIVATE_CODE void LockSingleStub(PSTUB);
  33. PRIVATE_CODE void UnlockSingleStub(PSTUB);
  34. #if defined(DEBUG) || defined(VSTF)
  35. PRIVATE_CODE BOOL IsValidStubType(STUBTYPE);
  36. #endif
  37. #ifdef DEBUG
  38. PRIVATE_CODE LPCTSTR GetStubName(PCSTUB);
  39. #endif
  40. /* Module Variables
  41. *******************/
  42. /* stub type descriptors */
  43. /* Cast off compiler complaints about pointer argument mismatch. */
  44. PRIVATE_DATA CONST STUBTYPEDESCRIPTOR Mrgcstd[] =
  45. {
  46. /* object twin STUB descriptor */
  47. {
  48. (UNLINKSTUBPROC)UnlinkObjectTwin,
  49. (DESTROYSTUBPROC)DestroyObjectTwin,
  50. LockSingleStub,
  51. UnlockSingleStub
  52. },
  53. /* twin family STUB descriptor */
  54. {
  55. (UNLINKSTUBPROC)UnlinkTwinFamily,
  56. (DESTROYSTUBPROC)DestroyTwinFamily,
  57. LockSingleStub,
  58. UnlockSingleStub
  59. },
  60. /* folder pair STUB descriptor */
  61. {
  62. (UNLINKSTUBPROC)UnlinkFolderPair,
  63. (DESTROYSTUBPROC)DestroyFolderPair,
  64. (LOCKSTUBPROC)LockFolderPair,
  65. (UNLOCKSTUBPROC)UnlockFolderPair
  66. }
  67. };
  68. /***************************** Private Functions *****************************/
  69. /*
  70. ** LockSingleStub()
  71. **
  72. **
  73. **
  74. ** Arguments:
  75. **
  76. ** Returns:
  77. **
  78. ** Side Effects: none
  79. */
  80. PRIVATE_CODE void LockSingleStub(PSTUB ps)
  81. {
  82. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  83. ASSERT(IsStubFlagClear(ps, STUB_FL_UNLINKED));
  84. ASSERT(ps->ulcLock < ULONG_MAX);
  85. ps->ulcLock++;
  86. return;
  87. }
  88. /*
  89. ** UnlockSingleStub()
  90. **
  91. **
  92. **
  93. ** Arguments:
  94. **
  95. ** Returns:
  96. **
  97. ** Side Effects: none
  98. */
  99. PRIVATE_CODE void UnlockSingleStub(PSTUB ps)
  100. {
  101. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  102. if (EVAL(ps->ulcLock > 0))
  103. {
  104. ps->ulcLock--;
  105. if (! ps->ulcLock &&
  106. IsStubFlagSet(ps, STUB_FL_UNLINKED))
  107. DestroyStub(ps);
  108. }
  109. return;
  110. }
  111. #if defined(DEBUG) || defined(VSTF)
  112. /*
  113. ** IsValidStubType()
  114. **
  115. **
  116. **
  117. ** Arguments:
  118. **
  119. ** Returns:
  120. **
  121. ** Side Effects: none
  122. */
  123. PRIVATE_CODE BOOL IsValidStubType(STUBTYPE st)
  124. {
  125. BOOL bResult;
  126. switch (st)
  127. {
  128. case ST_OBJECTTWIN:
  129. case ST_TWINFAMILY:
  130. case ST_FOLDERPAIR:
  131. bResult = TRUE;
  132. break;
  133. default:
  134. bResult = FALSE;
  135. ERROR_OUT((TEXT("IsValidStubType(): Invalid STUB type %d."),
  136. st));
  137. }
  138. return(bResult);
  139. }
  140. #endif
  141. #ifdef DEBUG
  142. /*
  143. ** GetStubName()
  144. **
  145. **
  146. **
  147. ** Arguments:
  148. **
  149. ** Returns: TWINRESULT
  150. **
  151. ** Side Effects: none
  152. */
  153. PRIVATE_CODE LPCTSTR GetStubName(PCSTUB pcs)
  154. {
  155. LPCTSTR pcszStubName;
  156. ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  157. switch (pcs->st)
  158. {
  159. case ST_OBJECTTWIN:
  160. pcszStubName = TEXT("object twin");
  161. break;
  162. case ST_TWINFAMILY:
  163. pcszStubName = TEXT("twin family");
  164. break;
  165. case ST_FOLDERPAIR:
  166. pcszStubName = TEXT("folder twin");
  167. break;
  168. default:
  169. ERROR_OUT((TEXT("GetStubName() called on unrecognized stub type %d."),
  170. pcs->st));
  171. pcszStubName = TEXT("UNKNOWN");
  172. break;
  173. }
  174. ASSERT(IS_VALID_STRING_PTR(pcszStubName, CSTR));
  175. return(pcszStubName);
  176. }
  177. #endif
  178. /****************************** Public Functions *****************************/
  179. /*
  180. ** InitStub()
  181. **
  182. ** Initializes a stub.
  183. **
  184. ** Arguments: ps - pointer to stub to be initialized
  185. ** st - type of stub
  186. **
  187. ** Returns: void
  188. **
  189. ** Side Effects: none
  190. */
  191. PUBLIC_CODE void InitStub(PSTUB ps, STUBTYPE st)
  192. {
  193. ASSERT(IS_VALID_WRITE_PTR(ps, STUB));
  194. ASSERT(IsValidStubType(st));
  195. ps->st = st;
  196. ps->ulcLock = 0;
  197. ps->dwFlags = 0;
  198. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  199. return;
  200. }
  201. /*
  202. ** DestroyStub()
  203. **
  204. ** Destroys a stub.
  205. **
  206. ** Arguments: ps - pointer to stub to be destroyed
  207. **
  208. ** Returns: TWINRESULT
  209. **
  210. ** Side Effects: Depends upon stub type.
  211. */
  212. PUBLIC_CODE TWINRESULT DestroyStub(PSTUB ps)
  213. {
  214. TWINRESULT tr;
  215. PCSTUBTYPEDESCRIPTOR pcstd;
  216. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  217. #ifdef DEBUG
  218. if (IsStubFlagSet(ps, STUB_FL_UNLINKED) &&
  219. ps->ulcLock > 0)
  220. WARNING_OUT((TEXT("DestroyStub() called on unlinked locked %s stub %#lx."),
  221. GetStubName(ps),
  222. ps));
  223. #endif
  224. pcstd = GetStubTypeDescriptor(ps);
  225. /* Is the stub already unlinked? */
  226. if (IsStubFlagSet(ps, STUB_FL_UNLINKED))
  227. /* Yes. */
  228. tr = TR_SUCCESS;
  229. else
  230. /* No. Unlink it. */
  231. tr = (*(pcstd->UnlinkStub))(ps);
  232. /* Is the stub still locked? */
  233. if (tr == TR_SUCCESS && ! ps->ulcLock)
  234. /* No. Wipe it out. */
  235. (*(pcstd->DestroyStub))(ps);
  236. return(tr);
  237. }
  238. /*
  239. ** LockStub()
  240. **
  241. **
  242. **
  243. ** Arguments:
  244. **
  245. ** Returns:
  246. **
  247. ** Side Effects: none
  248. */
  249. PUBLIC_CODE void LockStub(PSTUB ps)
  250. {
  251. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  252. (*(GetStubTypeDescriptor(ps)->LockStub))(ps);
  253. return;
  254. }
  255. /*
  256. ** UnlockStub()
  257. **
  258. ** Unlocks a stub. Carries out any pending deletion on the stub.
  259. **
  260. ** Arguments: ps - pointer to stub to be unlocked
  261. **
  262. ** Returns: void
  263. **
  264. ** Side Effects: If the stub is unlinked and the lock count decreases to 0
  265. ** after unlocking, the stub is deleted.
  266. */
  267. PUBLIC_CODE void UnlockStub(PSTUB ps)
  268. {
  269. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  270. (*(GetStubTypeDescriptor(ps)->UnlockStub))(ps);
  271. return;
  272. }
  273. /*
  274. ** GetStubFlags()
  275. **
  276. **
  277. **
  278. ** Arguments:
  279. **
  280. ** Returns:
  281. **
  282. ** Side Effects: none
  283. */
  284. PUBLIC_CODE DWORD GetStubFlags(PCSTUB pcs)
  285. {
  286. ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  287. return(pcs->dwFlags);
  288. }
  289. /*
  290. ** SetStubFlag()
  291. **
  292. ** Sets given flag in a stub. Other flags in stub are not affected.
  293. **
  294. ** Arguments: ps - pointer to stub whose flags are to be set
  295. **
  296. ** Returns: void
  297. **
  298. ** Side Effects: none
  299. */
  300. PUBLIC_CODE void SetStubFlag(PSTUB ps, DWORD dwFlags)
  301. {
  302. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  303. ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  304. SET_FLAG(ps->dwFlags, dwFlags);
  305. return;
  306. }
  307. /*
  308. ** ClearStubFlag()
  309. **
  310. ** Clears given flag in a stub. Other flags in stub are not affected.
  311. **
  312. ** Arguments: ps - pointer to stub whose flags are to be set
  313. **
  314. ** Returns: void
  315. **
  316. ** Side Effects: none
  317. */
  318. PUBLIC_CODE void ClearStubFlag(PSTUB ps, DWORD dwFlags)
  319. {
  320. ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  321. ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  322. CLEAR_FLAG(ps->dwFlags, dwFlags);
  323. return;
  324. }
  325. /*
  326. ** IsStubFlagSet()
  327. **
  328. **
  329. **
  330. ** Arguments:
  331. **
  332. ** Returns:
  333. **
  334. ** Side Effects: none
  335. */
  336. PUBLIC_CODE BOOL IsStubFlagSet(PCSTUB pcs, DWORD dwFlags)
  337. {
  338. ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  339. ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  340. return(IS_FLAG_SET(pcs->dwFlags, dwFlags));
  341. }
  342. /*
  343. ** IsStubFlagClear()
  344. **
  345. **
  346. **
  347. ** Arguments:
  348. **
  349. ** Returns:
  350. **
  351. ** Side Effects: none
  352. */
  353. PUBLIC_CODE BOOL IsStubFlagClear(PCSTUB pcs, DWORD dwFlags)
  354. {
  355. ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  356. ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  357. return(IS_FLAG_CLEAR(pcs->dwFlags, dwFlags));
  358. }
  359. #ifdef VSTF
  360. /*
  361. ** IsValidPCSTUB()
  362. **
  363. **
  364. **
  365. ** Arguments:
  366. **
  367. ** Returns:
  368. **
  369. ** Side Effects: none
  370. */
  371. PUBLIC_CODE BOOL IsValidPCSTUB(PCSTUB pcs)
  372. {
  373. BOOL bResult;
  374. if (IS_VALID_READ_PTR(pcs, CSTUB) &&
  375. IsValidStubType(pcs->st) &&
  376. FLAGS_ARE_VALID(pcs->dwFlags, ALL_STUB_FLAGS))
  377. bResult = TRUE;
  378. else
  379. bResult = FALSE;
  380. return(bResult);
  381. }
  382. #endif