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.

404 lines
9.4 KiB

  1. // implementation for app specific data
  2. #pragma data_seg(".text")
  3. #define INITGUID
  4. #include <objbase.h>
  5. #include <initguid.h>
  6. #include "SyncHndl.h"
  7. #include "handler.h"
  8. #include "priv.h"
  9. #include "base.h"
  10. #pragma data_seg()
  11. #include <tchar.h>
  12. extern HINSTANCE g_hmodThisDll; // Handle to this DLL itself.
  13. char szCLSIDDescription[] = "Briefcase OneStop Handler";
  14. void StripBriefcaseIni(TCHAR *szBriefCasePath)
  15. {
  16. TCHAR *pszTemp;
  17. pszTemp = szBriefCasePath + _tcslen(szBriefCasePath);
  18. while (pszTemp > szBriefCasePath && *pszTemp != '\\')
  19. {
  20. --pszTemp;
  21. }
  22. *pszTemp = '\0';
  23. }
  24. COneStopHandler* CreateHandlerObject()
  25. {
  26. return new CBriefHandler();
  27. }
  28. STDMETHODIMP CBriefHandler::DestroyHandler()
  29. {
  30. delete this;
  31. return NOERROR;
  32. }
  33. STDMETHODIMP CBriefHandler::Initialize(DWORD dwReserved,DWORD dwSyncFlags,
  34. DWORD cbCookie,const BYTE *lpCookie)
  35. {
  36. HRESULT hr = E_FAIL;
  37. DWORD dwBriefcaseCount = 0; // number of briefcases on this machine.
  38. LPBRIEFCASESTG pbrfstg = NULL;
  39. // if no data, then enumerate all available briefcase files
  40. // if there is cookie data, only get the specified briefcase
  41. // briefcase specific.
  42. // see if briefcase is available and if there is at least one item
  43. hr = CoCreateInstance(CLSID_BriefCase, NULL, CLSCTX_INPROC_SERVER,
  44. IID_IBriefcaseStg2, (void **) &pbrfstg);
  45. if (NOERROR == hr)
  46. {
  47. TCHAR szBriefCasePath[MAX_PATH];
  48. HRESULT hrEnum;
  49. if (0 != cbCookie)
  50. {
  51. memcpy(szBriefCasePath,lpCookie,cbCookie);
  52. hrEnum = NOERROR;
  53. }
  54. else
  55. {
  56. hrEnum = pbrfstg->FindFirst(szBriefCasePath,MAX_PATH);
  57. // actually get path all the way to the briefcase INI,
  58. // Just need folder
  59. if (NOERROR == hrEnum)
  60. {
  61. StripBriefcaseIni(szBriefCasePath);
  62. }
  63. }
  64. while (NOERROR == hrEnum)
  65. {
  66. ULONG ulPathLength;
  67. ulPathLength = _tcslen(szBriefCasePath);
  68. if (ulPathLength > 0 && ulPathLength < MAX_PATH)
  69. { // found a valid briefcase
  70. LPHANDLERITEM pOfflineItem;
  71. LPSYNCMGRHANDLERITEMS pOfflineItemsHolder;
  72. TCHAR *pszFriendlyName;
  73. #ifndef UNICODE
  74. WCHAR wszBriefcaseName[MAX_PATH];
  75. #endif // UNICODE
  76. // add the item to the enumerator.
  77. if (NULL == (pOfflineItemsHolder = GetOfflineItemsHolder()) )
  78. { // if first item, set up the enumerator.
  79. pOfflineItemsHolder = CreateOfflineHandlerItemsList();
  80. // if still NULL, break out of loop
  81. if (NULL == pOfflineItemsHolder)
  82. break;
  83. SetOfflineItemsHolder(pOfflineItemsHolder);
  84. }
  85. // add the item to the list.
  86. if (pOfflineItem = (LPHANDLERITEM) AddOfflineItemToList(pOfflineItemsHolder,sizeof(HANDLERITEM)) )
  87. {
  88. // OFFLINEITEMID offType;
  89. memcpy(pOfflineItem->szBriefcasePath,szBriefCasePath,
  90. (ulPathLength + 1) * sizeof(TCHAR));
  91. // add briefcase specific data
  92. pOfflineItem->baseItem.offlineItem.cbSize = sizeof(SYNCMGRITEM);
  93. pOfflineItem->baseItem.offlineItem.dwItemState = SYNCMGRITEMSTATE_CHECKED;
  94. pOfflineItem->baseItem.offlineItem.hIcon =
  95. LoadIcon(g_hmodThisDll,MAKEINTRESOURCE(IDI_BRIEFCASE));
  96. // set HASPROPERTIES flag for testing
  97. pOfflineItem->baseItem.offlineItem.dwFlags = SYNCMGRITEM_HASPROPERTIES;
  98. // for now, just use the path as the description
  99. // need to change this.
  100. pszFriendlyName = szBriefCasePath + ulPathLength;
  101. while ( (pszFriendlyName - 1) >= szBriefCasePath
  102. && TEXT('\\') != *(pszFriendlyName -1))
  103. {
  104. --pszFriendlyName;
  105. }
  106. // if we are not already unicode, have to convert now
  107. #ifndef UNICODE
  108. MultiByteToWideChar(CP_ACP,0,pszFriendlyName,-1,
  109. pOfflineItem->baseItem.offlineItem.wszItemName,MAX_SYNCMGRITEMNAME);
  110. #else
  111. // already unicode, just copy it in.
  112. memcpy(pOfflineItem->baseItem.offlineItem.wszItemName,
  113. pszFriendlyName,(ulPathLength + 1)*sizeof(TCHAR));
  114. #endif // UNICODE
  115. #ifndef UNICODE
  116. MultiByteToWideChar(CP_ACP,0,szBriefCasePath,-1,
  117. wszBriefcaseName,MAX_PATH);
  118. GetItemIdForHandlerItem(CLSID_OneStopHandler,
  119. wszBriefcaseName,
  120. &pOfflineItem->baseItem.offlineItem.ItemID,TRUE);
  121. #else
  122. GetItemIdForHandlerItem(CLSID_OneStopHandler,
  123. szBriefCasePath,
  124. &pOfflineItem->baseItem.offlineItem.ItemID,TRUE);
  125. #endif // UNICODE
  126. // don't do anything on the status for now.
  127. // pOfflineItem->offlineItem.wszStatus = NULL;
  128. ++dwBriefcaseCount; // increment the briefcase count.
  129. }
  130. }
  131. if (0 != cbCookie)
  132. {
  133. hrEnum = S_FALSE;
  134. }
  135. else
  136. {
  137. hrEnum = pbrfstg->FindNext(szBriefCasePath,MAX_PATH);
  138. if (NOERROR == hrEnum)
  139. {
  140. StripBriefcaseIni(szBriefCasePath);
  141. }
  142. }
  143. }
  144. }
  145. if (pbrfstg)
  146. pbrfstg->Release();
  147. return dwBriefcaseCount ? S_OK: S_FALSE; // if have at least one briefcase then return true.
  148. }
  149. STDMETHODIMP CBriefHandler::GetHandlerInfo(LPSYNCMGRHANDLERINFO *ppSyncMgrHandlerInfo)
  150. {
  151. return E_NOTIMPL;
  152. }
  153. // for test, just pull up a message box.
  154. STDMETHODIMP CBriefHandler::ShowProperties(HWND hwnd,REFSYNCMGRITEMID dwItemID)
  155. {
  156. MessageBox(hwnd,TEXT("Briefcase"),TEXT("Handler"),1);
  157. return NOERROR;
  158. }
  159. STDMETHODIMP CBriefHandler::PrepareForSync(ULONG cbNumItems,SYNCMGRITEMID *pItemIDs,
  160. HWND hwndParent,DWORD dwReserved)
  161. {
  162. HRESULT hr = NOERROR;
  163. LPSYNCMGRSYNCHRONIZECALLBACK pCallback = GetOfflineSynchronizeCallback();
  164. LPHANDLERITEM pOfflineItem = (LPHANDLERITEM) GetOfflineItemsHolder()->pFirstOfflineItem;
  165. if (!pOfflineItem)
  166. {
  167. return S_FALSE;
  168. }
  169. // loop through the selected offline items
  170. while (pOfflineItem)
  171. {
  172. ULONG NumItemsCount = cbNumItems;
  173. SYNCMGRITEMID *pCurItemID = pItemIDs;
  174. // see if item has been specified to sync, if not, update the state
  175. // to reflect this else go ahead and prepare.
  176. pOfflineItem->baseItem.offlineItem.dwItemState = SYNCMGRITEMSTATE_UNCHECKED;
  177. while (NumItemsCount--)
  178. {
  179. if (IsEqualGUID(*pCurItemID,pOfflineItem->baseItem.offlineItem.ItemID))
  180. {
  181. pOfflineItem->baseItem.offlineItem.dwItemState = SYNCMGRITEMSTATE_CHECKED;
  182. break;
  183. }
  184. ++pCurItemID;
  185. }
  186. if (SYNCMGRITEMSTATE_CHECKED == pOfflineItem->baseItem.offlineItem.dwItemState)
  187. {
  188. LPBRIEFCASESTG pbrfstg = NULL;
  189. hr = CoCreateInstance(CLSID_BriefCase, NULL, CLSCTX_INPROC_SERVER,
  190. IID_IBriefcaseStg2, (void **) &pbrfstg);
  191. if (NOERROR == hr)
  192. {
  193. if (NOERROR == (hr =
  194. pbrfstg->Initialize(pOfflineItem->szBriefcasePath,hwndParent)) )
  195. {
  196. hr = pbrfstg->PrepForSync(hwndParent ,GetOfflineSynchronizeCallback(),
  197. pOfflineItem->baseItem.offlineItem.ItemID);
  198. }
  199. if (NOERROR == hr)
  200. {
  201. pOfflineItem->pbrfstg = pbrfstg;
  202. }
  203. else
  204. {
  205. LPSYNCMGRSYNCHRONIZECALLBACK pCallback = GetOfflineSynchronizeCallback();
  206. pbrfstg->Release();
  207. // let user know that the sync is done
  208. if (pCallback)
  209. {
  210. SYNCMGRPROGRESSITEM progItem;
  211. progItem.mask = SYNCMGRPROGRESSITEM_STATUSTYPE
  212. | SYNCMGRPROGRESSITEM_PROGVALUE
  213. | SYNCMGRPROGRESSITEM_MAXVALUE;
  214. progItem.dwStatusType = SYNCMGRSTATUS_SUCCEEDED;
  215. progItem.iProgValue = 1;
  216. progItem.iMaxValue = 1;
  217. pCallback->Progress((pOfflineItem->baseItem.offlineItem.ItemID),
  218. &progItem);
  219. }
  220. }
  221. }
  222. }
  223. pOfflineItem = (LPHANDLERITEM) pOfflineItem->baseItem.pNextOfflineItem;
  224. }
  225. if (pCallback)
  226. pCallback->PrepareForSyncCompleted(NOERROR);
  227. return S_OK; // always return S_OK
  228. }
  229. STDMETHODIMP CBriefHandler::Synchronize(HWND hwnd)
  230. {
  231. HRESULT hr = NOERROR;
  232. LPHANDLERITEM pOfflineItem = (LPHANDLERITEM) GetOfflineItemsHolder()->pFirstOfflineItem;
  233. LPSYNCMGRSYNCHRONIZECALLBACK pCallback = GetOfflineSynchronizeCallback();
  234. if (!pOfflineItem)
  235. {
  236. return S_FALSE;
  237. }
  238. while (pOfflineItem)
  239. {
  240. LPBRIEFCASESTG pbrfstg = NULL;
  241. if (NULL != (pbrfstg= pOfflineItem->pbrfstg)
  242. && SYNCMGRITEMSTATE_CHECKED == pOfflineItem->baseItem.offlineItem.dwItemState)
  243. {
  244. hr = pbrfstg->Synchronize(hwnd ,GetOfflineSynchronizeCallback(),
  245. pOfflineItem->baseItem.offlineItem.ItemID);
  246. pbrfstg->Release();
  247. // let user know that the sync is done
  248. if (pCallback)
  249. {
  250. SYNCMGRPROGRESSITEM progItem;
  251. progItem.mask = SYNCMGRPROGRESSITEM_STATUSTYPE
  252. | SYNCMGRPROGRESSITEM_PROGVALUE
  253. | SYNCMGRPROGRESSITEM_MAXVALUE;
  254. progItem.dwStatusType = FAILED(hr) ? SYNCMGRSTATUS_FAILED : SYNCMGRSTATUS_SUCCEEDED;
  255. progItem.iProgValue = 1;
  256. progItem.iMaxValue = 1;
  257. pCallback->Progress((pOfflineItem->baseItem.offlineItem.ItemID),
  258. &progItem);
  259. }
  260. }
  261. pOfflineItem = (LPHANDLERITEM) pOfflineItem->baseItem.pNextOfflineItem;
  262. }
  263. if (pCallback)
  264. pCallback->SynchronizeCompleted(NOERROR);
  265. return NOERROR; // always return NOERROR for now.
  266. }
  267. STDMETHODIMP CBriefHandler::SetItemStatus(REFSYNCMGRITEMID ItemID,DWORD dwSyncMgrStatus)
  268. {
  269. return E_NOTIMPL;
  270. }
  271. STDMETHODIMP CBriefHandler::ShowError(HWND hWndParent,REFSYNCMGRERRORID ErrorID)
  272. {
  273. #ifdef _OBSOLETE
  274. LPHANDLERITEM pOfflineItem = (LPHANDLERITEM) GetOfflineItemsHolder()->pFirstOfflineItem;
  275. while (pOfflineItem) // loop through showing the results.
  276. {
  277. LPBRIEFCASESTG pbrfstg = NULL;
  278. if (NULL != (pbrfstg= pOfflineItem->pbrfstg))
  279. {
  280. pbrfstg->ShowError(hwnd,dwErrorID);
  281. pOfflineItem->pbrfstg = NULL;
  282. pbrfstg->Release();
  283. }
  284. pOfflineItem = (LPHANDLERITEM) pOfflineItem->baseItem.pNextOfflineItem;
  285. }
  286. return NOERROR; // always return NOERROR for now.
  287. #endif // _OBSOLETE
  288. return E_NOTIMPL;
  289. }