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.

216 lines
5.5 KiB

  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. WCHAR *Convert(char *psz)
  5. { int c;
  6. WCHAR *pwsz = new WCHAR [ c = strlen(psz) + 1 ];
  7. if (pwsz)
  8. mbstowcs(pwsz, psz, c);
  9. return pwsz;
  10. }
  11. #define CHECKNE(hr, stat, string, errRet) \
  12. if (hr != stat) { iLine = __LINE__; pszErr = string; goto errRet; }
  13. HRESULT TouchFile(WCHAR *pwszSource)
  14. {
  15. FILETIME ftc;
  16. SYSTEMTIME st;
  17. GetSystemTime(&st);
  18. SystemTimeToFileTime(&st, &ftc);
  19. return StgSetTimes(pwszSource, &ftc, NULL, NULL);
  20. }
  21. HRESULT CreateLink(WCHAR *pwszClient, WCHAR *pwszSource)
  22. {
  23. HRESULT hr;
  24. IBindCtx *pbc=NULL;
  25. ULONG ulEaten;
  26. IMoniker *pmkSource=NULL;
  27. IStorage *pstg=NULL;
  28. IOleObject *poo=NULL;
  29. IMoniker *pmkThis=NULL;
  30. IMoniker *pmkLink=NULL;
  31. IPersistStorage *pps=NULL;
  32. char *pszErr;
  33. int iLine=0;
  34. hr = CreateFileMoniker(pwszClient, &pmkThis);
  35. CHECKNE(hr, S_OK, "CreateFileMoniker", errRet);
  36. hr = CreateItemMoniker(L"!", L"Link", &pmkLink);
  37. CHECKNE(hr, S_OK, "CreateItemMoniker", errRet);
  38. hr = StgCreateDocfile(pwszClient, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
  39. 0, &pstg);
  40. CHECKNE(hr, S_OK, "StgCreateDocfile", errRet);
  41. hr = CreateBindCtx(0, &pbc);
  42. CHECKNE(hr, S_OK, "CreateBindCtx", errRet);
  43. hr = MkParseDisplayName(pbc, pwszSource, &ulEaten, &pmkSource);
  44. CHECKNE(hr, S_OK, "MkParseDisplayName", errRet);
  45. hr = OleCreateLink(pmkSource, IID_IOleObject, OLERENDER_NONE, NULL, NULL, pstg, (void**)&poo);
  46. CHECKNE(hr, S_OK, "OleCreateLink", errRet);
  47. hr = poo->SetMoniker(OLEWHICHMK_CONTAINER, pmkThis);
  48. CHECKNE(hr, S_OK, "SetMonikerOLEWHICHMK_CONTAINER", errRet);
  49. hr = poo->SetMoniker(OLEWHICHMK_OBJREL, pmkLink);
  50. CHECKNE(hr, S_OK, "SetMonikerOLEWHICHMK_OBJREL", errRet);
  51. hr = poo->QueryInterface(IID_IPersistStorage, (void**)&pps);
  52. CHECKNE(hr, S_OK, "QueryInterface(IID_IPersistStorage", errRet);
  53. hr = OleSave(pps, pstg, TRUE);
  54. CHECKNE(hr, S_OK, "OleSave", errRet);
  55. errRet:
  56. if (hr != S_OK)
  57. printf("CreateLink at %s line %d with hr=%08x\n", pszErr, iLine, hr);
  58. if (pbc) pbc->Release();
  59. if (pmkSource) pmkSource->Release();
  60. if (pstg) pstg->Release();
  61. if (poo) poo->Release();
  62. if (pmkThis) pmkThis->Release();
  63. if (pmkLink) pmkLink->Release();
  64. if (pps) pps->Release();
  65. return hr;
  66. }
  67. HRESULT ResolveLink(WCHAR *pwszClient, WCHAR *pwszSource, BOOL fReSave)
  68. {
  69. HRESULT hr;
  70. IStorage *pstg = NULL;
  71. IOleLink *pol = NULL;
  72. WCHAR *pwszSourceFound = NULL;
  73. IPersistStorage *pps = NULL;
  74. char *pszErr;
  75. int iLine;
  76. hr = StgOpenStorage(pwszClient, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
  77. NULL, 0, &pstg);
  78. CHECKNE(hr, S_OK, "StgOpenStorage(pwszClient", errRet);
  79. hr = OleLoad(pstg, IID_IOleLink, NULL, (void**)&pol);
  80. CHECKNE(hr, S_OK, "OleLoad(pstg, IID_IOleLink", errRet);
  81. hr = pol->BindToSource(0, NULL);
  82. CHECKNE(hr, S_OK, "pol->BindToSource", errRet);
  83. hr = pol->GetSourceDisplayName(&pwszSourceFound);
  84. CHECKNE(hr, S_OK, "pol->GetSourceDisplayName", errRet);
  85. if (wcsicmp(pwszSourceFound, pwszSource) != 0)
  86. {
  87. printf("SourceFound=%ls, SourceExpected=%ls\n", pwszSourceFound, pwszSource);
  88. pszErr = "'path compare'";
  89. hr = E_FAIL;
  90. goto errRet;
  91. }
  92. if (fReSave)
  93. {
  94. hr = pol->QueryInterface(IID_IPersistStorage, (void**)&pps);
  95. CHECKNE(hr, S_OK, "pol->QueryInterface(IID_IPersistStorage", errRet);
  96. hr = OleSave(pps, pstg, TRUE);
  97. CHECKNE(hr, S_OK, "OleSave(pps, pstg, TRUE)", errRet);
  98. }
  99. errRet:
  100. if (hr != S_OK)
  101. printf("ResolveLink at %s line %d with hr=%08x\n", pszErr, iLine, hr);
  102. CoTaskMemFree(pwszSourceFound);
  103. if (pol) pol->Release();
  104. if (pstg) pstg->Release();
  105. if (pps) pps->Release();
  106. return hr;
  107. }
  108. int __cdecl main(int argc, char **argv)
  109. {
  110. char * pszExit = "TEST FAILED.";
  111. int iExit = 1;
  112. WCHAR *pwszClient = NULL;
  113. WCHAR *pwszSource = NULL;
  114. HRESULT hr=E_FAIL;
  115. BOOL fArgsOk = FALSE;
  116. HRESULT hrExpected=S_OK;
  117. CoInitialize(NULL);
  118. OleInitialize(NULL);
  119. if (argc >= 3)
  120. {
  121. pwszClient = Convert(argv[2]);
  122. }
  123. if (argc >= 5)
  124. {
  125. pwszSource = Convert(argv[3]);
  126. sscanf(argv[4], "%x", &hrExpected);
  127. if (!pwszClient || !pwszSource)
  128. {
  129. pszExit = "Out of memory.";
  130. goto errExit;
  131. }
  132. }
  133. if (argc == 3)
  134. {
  135. if (stricmp(argv[1], "/t") == 0 || stricmp(argv[1], "-t") == 0)
  136. {
  137. // touch file creation date
  138. hr = TouchFile(pwszClient);
  139. fArgsOk = TRUE;
  140. }
  141. }
  142. else
  143. if (argc == 5)
  144. {
  145. if (stricmp(argv[1], "/c") == 0 || stricmp(argv[1], "-c") == 0)
  146. {
  147. // create link
  148. hr = CreateLink(pwszClient, pwszSource);
  149. fArgsOk = TRUE;
  150. }
  151. }
  152. else
  153. if (argc == 6)
  154. {
  155. if (stricmp(argv[1], "/r") == 0 || stricmp(argv[1], "-r") == 0)
  156. {
  157. // resolve link
  158. hr = ResolveLink(pwszClient, pwszSource, argv[5][0] == 's');
  159. fArgsOk = TRUE;
  160. }
  161. }
  162. if (!fArgsOk)
  163. {
  164. pszExit = "Usage: /c client source expected_status -- create .lts file linked to source\n"
  165. " /r client expected_source expected_status save/nosave -- resolve .lts file, checked linked to source\n"
  166. " expected_source is ignored(but required) if not found during resolve.\n"
  167. " /t source -- change the creation date\n";
  168. }
  169. else
  170. {
  171. if (hrExpected != hr)
  172. {
  173. printf("Expected status = %08X, actual status = %08X\n",
  174. hrExpected,
  175. hr);
  176. }
  177. else
  178. {
  179. pszExit = "TEST PASSED.";
  180. iExit = 0;
  181. }
  182. }
  183. errExit:
  184. OleUninitialize();
  185. CoUninitialize();
  186. delete pwszClient;
  187. delete pwszSource;
  188. puts(pszExit);
  189. return iExit;
  190. }