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.

337 lines
9.8 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /* File: dinterp.c */
  4. /**************************************************************************/
  5. /***** DETECT COMPONENT - Detect Interpreter
  6. /**************************************************************************/
  7. /* Detect component return code symbol table variable name */
  8. CHP szStfRCSym[] = "STF_DETECT_OUTCOME";
  9. HANDLE hInstCaller = NULL;
  10. /* Component error variable detect error values
  11. ** (ordered by priority)
  12. */
  13. SZ rgszDrc[] =
  14. {
  15. "DLLNOTFOUND",
  16. "OUTOFMEM",
  17. "CMDNOTFOUND",
  18. "CMDFAILED",
  19. "OKAY"
  20. };
  21. #define drcDllNotFound 0
  22. #define drcOutOfMem 1
  23. #define drcCmdNotFound 2
  24. #define drcCmdFailed 3
  25. #define drcOkay 4
  26. #define drcMin 0
  27. #define drcMax 5
  28. #if DBG
  29. /*** REVIEW: Out of memory TEST functions (from _comstf.h) ***/
  30. extern CB APIENTRY CbSetAllocOpsCur(CB);
  31. extern CB APIENTRY CbGetAllocOpsCur(VOID);
  32. extern CB APIENTRY CbSetAllocOpsForceFailure(CB);
  33. extern CB APIENTRY CbGetAllocOpsForceFailure(VOID);
  34. #endif /* DBG */
  35. /*
  36. ** Purpose:
  37. ** Shell interpreter detect command handler.
  38. ** Called by Shell interpreter.
  39. ** Arguments:
  40. ** hinst, hwnd : Windows stuff
  41. ** rgsz : array of arguments (NULL terminated)
  42. ** cItems : count of arguments (must be 1)
  43. ** Returns:
  44. ** fFalse if a vital detect operation fails or if a referrenced
  45. ** detect command DLL cannot be loaded,
  46. ** fTrue otherwise.
  47. **************************************************************************/
  48. BOOL APIENTRY FDetectEntryPoint(HANDLE hInst,HWND hWnd,RGSZ rgsz,USHORT cItems)
  49. {
  50. if (hInst == (HANDLE)NULL
  51. || hWnd == (HWND)NULL
  52. || rgsz == (RGSZ)NULL
  53. || *rgsz == (SZ)NULL
  54. || cItems != 1
  55. || *(rgsz + 1) != (SZ)NULL)
  56. {
  57. Assert(fFalse);
  58. return(fFalse);
  59. }
  60. hInstCaller = hInst;
  61. return(FDetectInfSection(hWnd, rgsz[0]));
  62. }
  63. /*
  64. ** Purpose:
  65. ** Traverses the given section evaluating any detect commands
  66. ** found and setting the associated symbol in the symbol table.
  67. ** Also sets the detect outcome variable (STF_DETECT_OUTCOME)
  68. ** in the symbol table to one of the following (in order of
  69. ** priority):
  70. **
  71. ** "DLLNOTFOUND" Requested detect command DLL not found
  72. ** "OUTOFMEM" Out of memory error occured
  73. ** "CMDNOTFOUND" Requested detect command not found
  74. ** "CMDFAILED" Requested detect command failed
  75. ** "OKAY" All detect commands completed okay
  76. **
  77. ** Arguments:
  78. ** szSection: non-NULL, non-empty section name.
  79. ** Notes:
  80. ** Requires that the current INF structure was initialized with a
  81. ** successful call to GrcOpenInf().
  82. ** Requires that the Symbol Table was initialized with a successful
  83. ** call to FInitSymTab().
  84. ** Returns:
  85. ** fFalse if a vital detect operation fails or if a referrenced
  86. ** detect command DLL cannot be loaded,
  87. ** fTrue otherwise.
  88. **************************************************************************/
  89. BOOL APIENTRY FDetectInfSection(HWND hwnd,SZ szSection)
  90. {
  91. RGSZ rgsz = rgszNull;
  92. SZ szKey = szNull;
  93. SZ szValue = szNull;
  94. CHP szLibCur[cchpFullPathBuf];
  95. HANDLE hLibCur = hNull;
  96. PFNCMD pfncmd;
  97. INT Line;
  98. BOOL fOkay = fTrue;
  99. UINT cFields;
  100. DRC drcSet = drcOkay;
  101. DRC drc;
  102. AssertDataSeg();
  103. // PreCondSymTabInit(fFalse); *** REVIEW: can't use with dll ***
  104. // PreCondInfOpen(fFalse);
  105. ChkArg(szSection != (SZ)NULL &&
  106. *szSection != '\0' &&
  107. !FWhiteSpaceChp(*szSection), 1, fFalse);
  108. *szLibCur = '\0';
  109. Line = FindFirstLineFromInfSection(szSection);
  110. while(Line != -1)
  111. {
  112. SdAtNewLine(Line);
  113. if(FKeyInInfLine(Line)
  114. && (cFields = CFieldsInInfLine(Line)) >= cFieldDetMin)
  115. {
  116. drc = drcOkay;
  117. if((rgsz = RgszFromInfScriptLine(Line,cFields)) == rgszNull)
  118. {
  119. drc = drcOutOfMem;
  120. goto NextCmd;
  121. }
  122. if(CrcStringCompare(rgsz[iszDetSym], szDetSym) != crcEqual)
  123. goto NextCmd;
  124. if(!FLoadDetectLib(rgsz[iszLib], szLibCur, &hLibCur))
  125. {
  126. drc = drcDllNotFound;
  127. fOkay = fFalse;
  128. goto NextCmd;
  129. }
  130. if((pfncmd = (PFNCMD)GetProcAddress(hLibCur, rgsz[iszCmd]))
  131. == pfncmdNull)
  132. {
  133. #if DBG
  134. MessBoxSzSz("Unknown Detect Command", rgsz[iszCmd]);
  135. #endif
  136. drc = drcCmdNotFound;
  137. goto NextCmd;
  138. }
  139. if((drc = DrcGetDetectValue(&szValue, pfncmd,
  140. rgsz+iszArg, cFields-iszArg)) != drcOkay)
  141. {
  142. #if DBG
  143. if(drc == drcCmdFailed)
  144. MessBoxSzSz("Detect Command Failed", rgsz[iszCmd]);
  145. #endif
  146. goto NextCmd;
  147. }
  148. if((szKey = SzGetNthFieldFromInfLine(Line,0)) == szNull)
  149. {
  150. drc = drcOutOfMem;
  151. goto NextCmd;
  152. }
  153. if(!FAddSymbolValueToSymTab(szKey, szValue))
  154. drc = drcOutOfMem;
  155. NextCmd:
  156. if(drc < drcSet)
  157. drcSet = drc;
  158. if(szValue != szNull)
  159. SFree(szValue);
  160. if(szKey != szNull)
  161. SFree(szKey);
  162. if(rgsz != (RGSZ)szNull)
  163. FFreeRgsz(rgsz);
  164. szValue = szKey = szNull;
  165. rgsz = rgszNull;
  166. if(!fOkay)
  167. break;
  168. }
  169. Line = FindNextLineFromInf(Line);
  170. }
  171. if(hLibCur >= hLibMin)
  172. if(*szLibCur != '|')
  173. FreeLibrary(hLibCur);
  174. while(!FAddSymbolValueToSymTab(szStfRCSym, rgszDrc[drcSet]))
  175. {
  176. if(!FHandleOOM(hwnd))
  177. fOkay = fFalse;
  178. }
  179. return(fOkay);
  180. }
  181. HANDLE APIENTRY StfLoadLibrary(SZ szLib)
  182. {
  183. INT cchp;
  184. SZ szCWD, szCur;
  185. SZ szLastBackSlash = (SZ)NULL;
  186. HANDLE hDll;
  187. if ((szCur = szCWD = (SZ)SAlloc((CB)4096)) == (SZ)NULL)
  188. return(0);
  189. if ((cchp = GetModuleFileName(hInstCaller, (LPSTR)szCur, 4095)) >= 4095)
  190. {
  191. SFree(szCur);
  192. return((HANDLE)2);
  193. }
  194. *(szCur + cchp) = '\0';
  195. while (*szCur != '\0')
  196. if (*szCur++ == '\\')
  197. szLastBackSlash = szCur;
  198. if (szLastBackSlash == (SZ)NULL)
  199. {
  200. SFree(szCWD);
  201. return((HANDLE)2);
  202. }
  203. *szLastBackSlash = '\0';
  204. EvalAssert(SzStrCat(szCWD, szLib) == szCWD);
  205. hDll = LoadLibrary((PfhOpenFile(szCWD, ofmExistRead) != NULL) ? szCWD
  206. : szLib);
  207. SFree(szCWD);
  208. return(hDll);
  209. }
  210. /*
  211. ** Purpose:
  212. ** Loads the given detect DLL if not already loaded, and
  213. ** frees the previously loaded DLL, if any.
  214. ** Arguments:
  215. ** szLib : name of library to load (must be non-szNull)
  216. ** szLibCurBuf : pointer into string buffer conatining name of
  217. ** library currently loaded, if any (empty string if none
  218. ** loaded).
  219. ** phLibCir : handle to currently loaded library.
  220. ** Notes:
  221. ** Assumes szLibCurBuf buffer is large enough for any DLL name.
  222. ** Returns:
  223. ** fTrue if given detect DLL loaded okay, fFalse if not.
  224. ** Modifies szLibCurBuf and phLibCur if new library is loaded.
  225. **************************************************************************/
  226. BOOL APIENTRY FLoadDetectLib(szLib, szLibCurBuf, phLibCur)
  227. SZ szLib;
  228. SZ szLibCurBuf;
  229. HANDLE *phLibCur;
  230. {
  231. ChkArg(szLib != szNull &&
  232. *szLib != '\0' &&
  233. !FWhiteSpaceChp(*szLib), 1, fFalse);
  234. ChkArg(szLibCurBuf != szNull, 2, fFalse);
  235. ChkArg(phLibCur != (HANDLE *)NULL, 3, fFalse);
  236. if(*szLib == '|') { // lib name is really a handle
  237. *phLibCur = LongToHandle(atol(szLib+1));
  238. *szLibCurBuf = '|';
  239. return(fTrue);
  240. }
  241. if(*szLibCurBuf == '\0'
  242. || CrcStringCompareI(szLibCurBuf, szLib) != crcEqual)
  243. {
  244. if(*phLibCur >= hLibMin)
  245. FreeLibrary(*phLibCur);
  246. *szLibCurBuf = '\0';
  247. if((*phLibCur = StfLoadLibrary(szLib)) < hLibMin)
  248. return(fFalse);
  249. Assert(strlen(szLib) < cchpFullPathBuf);
  250. EvalAssert(strcpy(szLibCurBuf, szLib) != szNull);
  251. }
  252. Assert(*phLibCur >= hLibMin);
  253. return(fTrue);
  254. }
  255. /*
  256. ** Purpose:
  257. ** Gets the value of a detect command and returns it in
  258. ** an allocated, zero terminated string.
  259. ** Arguments:
  260. ** psz : pointer to be set to result value string
  261. ** pfncmd : address of detect command function
  262. ** rgsz : array of command arguments (may be empty)
  263. ** cArgs : number of args in rgsz
  264. ** Returns:
  265. ** drcCmdFailed if detect command failed (returned 0)
  266. ** drcOutOfMem if out of memory error
  267. ** drcOkay if no error
  268. **************************************************************************/
  269. DRC APIENTRY DrcGetDetectValue(psz, pfncmd, rgsz, cArgs)
  270. SZ *psz;
  271. PFNCMD pfncmd;
  272. RGSZ rgsz;
  273. CB cArgs; // 1632
  274. {
  275. SZ szValue, szT;
  276. CB cbBuf = cbValBufDef;
  277. CB cbVal;
  278. if((szValue = (SZ)SAlloc(cbBuf)) == szNull)
  279. return(drcOutOfMem);
  280. Assert(cbBuf > 0);
  281. while((cbVal = (*pfncmd)(rgsz, (USHORT)cArgs, szValue, cbBuf)) > cbBuf) // 1632
  282. {
  283. if(cbVal > cbAllocMax)
  284. {
  285. SFree(szValue);
  286. return(drcCmdFailed);
  287. }
  288. if((szT = SRealloc((PB)szValue, cbVal)) == NULL)
  289. {
  290. SFree(szValue);
  291. return(drcOutOfMem);
  292. }
  293. szValue = szT;
  294. cbBuf = cbVal;
  295. }
  296. if(cbVal == 0)
  297. {
  298. SFree(szValue);
  299. return(drcCmdFailed);
  300. }
  301. Assert(szValue != szNull
  302. && (strlen(szValue)+1) == cbVal
  303. && cbVal <= cbBuf);
  304. if(cbVal < cbBuf)
  305. szValue = SRealloc(szValue,cbBuf);
  306. *psz = szValue;
  307. return(drcOkay);
  308. }