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.

439 lines
11 KiB

  1. /*
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. setting.cpp
  5. Abstract:
  6. CSetting object. Used to support Remote Assistance Channel settings.
  7. Revision History:
  8. created steveshi 08/23/00
  9. */
  10. #include "stdafx.h"
  11. #include "Rcbdyctl.h"
  12. #include "setting.h"
  13. #include "iphlpapi.h"
  14. #include "userenv.h"
  15. #include "shlobj.h"
  16. #include "stdio.h"
  17. #include "windowsx.h"
  18. #include "helper.h"
  19. #include "utils.h"
  20. const TCHAR cstrRCBDYINI[] = _T("RcBuddy.ini");
  21. const TCHAR cstrRCBDYAPP[] = _T("RcBuddyChannel");
  22. void CreatePassword(TCHAR* pass);
  23. extern HINSTANCE g_hInstance;
  24. INT_PTR APIENTRY IPDlgProc( HWND, UINT, WPARAM, LPARAM);
  25. PIP_ADAPTER_INFO g_pIp;
  26. PIP_ADDR_STRING g_pIpAddr;
  27. //extern "C"
  28. //{
  29. DWORD APIENTRY SquishAddress(WCHAR *szIp, WCHAR *szCompIp, size_t cszCompIp);
  30. DWORD APIENTRY ExpandAddress(WCHAR *szIp, WCHAR *szCompIp, size_t cszIp);
  31. //};
  32. //////////////////////////////////////////////////////////////////////////////
  33. // GetIPAddress
  34. // Return a list of current available IP address.
  35. // If multiple IP addresses are available, ";" will be used as delimiter.
  36. //////////////////////////////////////////////////////////////////////////////
  37. HRESULT CSetting::get_GetIPAddress(/*[out, retval]*/ BSTR *pVal)
  38. {
  39. HRESULT hr = S_FALSE; // In case no adapter
  40. PMIB_IPADDRTABLE pmib=NULL;
  41. ULONG ulSize = 0;
  42. DWORD dw;
  43. PIP_ADAPTER_INFO pAdpInfo = NULL;
  44. if (!pVal)
  45. {
  46. hr = E_INVALIDARG;
  47. goto done;
  48. }
  49. dw = GetAdaptersInfo(
  50. pAdpInfo,
  51. &ulSize );
  52. if (dw == ERROR_BUFFER_OVERFLOW)
  53. {
  54. pAdpInfo = (IP_ADAPTER_INFO*)malloc(ulSize);
  55. if (!pAdpInfo)
  56. {
  57. hr = E_OUTOFMEMORY;
  58. goto done;
  59. }
  60. dw = GetAdaptersInfo(
  61. pAdpInfo,
  62. &ulSize);
  63. if (dw == ERROR_SUCCESS)
  64. {
  65. if (pAdpInfo->Next != NULL ||
  66. pAdpInfo->IpAddressList.Next != NULL) // We got more than 1 IP Address
  67. {
  68. int iCount = 0;
  69. PIP_ADAPTER_INFO p;
  70. PIP_ADDR_STRING ps, psMem = NULL;
  71. CComBSTR t;
  72. for(p=pAdpInfo; p!=NULL; p=p->Next)
  73. {
  74. for(PIP_ADDR_STRING ps = &(p->IpAddressList); ps; ps=ps->Next)
  75. {
  76. if (strcmp(ps->IpAddress.String, "0.0.0.0") != 0) // Filter out ZERO address as ipconfig does
  77. {
  78. if (t.Length() > 0)
  79. t.Append(";");
  80. t.Append(ps->IpAddress.String);
  81. }
  82. }
  83. }
  84. if (t.Length() > 0)
  85. *pVal = t.Copy();
  86. else
  87. goto done;
  88. }
  89. else
  90. {
  91. // Only 1 IP address found.
  92. *pVal = CComBSTR(pAdpInfo->IpAddressList.IpAddress.String).Copy();
  93. }
  94. hr = S_OK;
  95. }
  96. }
  97. done:
  98. if (pAdpInfo)
  99. free(pAdpInfo);
  100. return hr;
  101. }
  102. /*********************************************************
  103. Func:
  104. get_GetUserTempFileName
  105. Abstract:
  106. Return a temp file name under user's profile directory
  107. *********************************************************/
  108. //HRESULT CSetting::get_GetUserTempFileName(/*[out, retval]*/ BSTR *pVal)
  109. /*
  110. {
  111. HRESULT hr = S_FALSE;
  112. TCHAR sFile[MAX_PATH + 256];
  113. if(FAILED(InitProfile()))
  114. goto done;
  115. // Get Temp file name
  116. if (!GetTempFileName(m_pProfileDir, _T("RC"), 0, &sFile[0]))
  117. goto done;
  118. *pVal = CComBSTR(sFile).Copy();
  119. hr = S_OK;
  120. done:
  121. return hr;
  122. }
  123. */
  124. /*********************************************************
  125. Func:
  126. GetProfileString
  127. Abstract:
  128. Get profile string inside the channel's setting file.
  129. Params:
  130. bstrSec: Section key.
  131. pVal: Output string (default is "0", if not found.)
  132. *********************************************************/
  133. /*
  134. HRESULT CSetting::GetProfileString(BSTR bstrSec, BSTR* pVal)
  135. {
  136. HRESULT hr = S_FALSE;
  137. TCHAR sBuf[512];
  138. DWORD dwSize;
  139. USES_CONVERSION;
  140. if (FAILED(InitProfile()))
  141. goto done;
  142. dwSize = GetPrivateProfileString(cstrRCBDYAPP,
  143. W2T(bstrSec),
  144. TEXT("0"), &sBuf[0], 512, m_pIniFile);
  145. *pVal = CComBSTR(sBuf).Copy();
  146. hr = S_OK;
  147. done:
  148. return hr;
  149. }
  150. */
  151. /*********************************************************
  152. Func:
  153. SetProfileString
  154. Abstract:
  155. Set profile string inside the channel's setting file.
  156. Params:
  157. bstrSec: Section key.
  158. bstrVal: New value
  159. *********************************************************/
  160. /*
  161. HRESULT CSetting::SetProfileString(BSTR bstrSec, BSTR bstrVal)
  162. {
  163. HRESULT hr = S_FALSE;
  164. USES_CONVERSION;
  165. if (FAILED(InitProfile()))
  166. goto done;
  167. if (!WritePrivateProfileString(cstrRCBDYAPP, W2T(bstrSec), W2T(bstrVal), m_pIniFile))
  168. goto done;
  169. hr = S_OK;
  170. done:
  171. return hr;
  172. }
  173. */
  174. //////////////////////////////////////////////////////////////////////////////////////
  175. // Helper functions used to support the above methods or properties
  176. /////////////////////////////
  177. /*********************************************************
  178. Func:
  179. InitProfile
  180. Abstract:
  181. Create the setting file.
  182. A RCIncidents subdir will be created under user's profile dir.
  183. A RcBuddy.ini file be created as the user's RA channel setting file.
  184. *********************************************************/
  185. /*
  186. HRESULT CSetting::InitProfile()
  187. {
  188. HRESULT hr = E_FAIL;
  189. if (m_pProfileDir && m_pIniFile) // No need to process
  190. return S_OK;
  191. if (m_pProfileDir || m_pIniFile) // Only one has value: Error. No need to process either.
  192. return E_FAIL;
  193. // Get User profile directory
  194. HANDLE hProcess = GetCurrentProcess();
  195. TCHAR* pPath = NULL;
  196. const TCHAR sSubDir[] = _T("\\Local Settings\\Application Data\\RcIncidents");
  197. TCHAR sPath[MAX_PATH];
  198. ULONG ulSize = sizeof(sPath) - sizeof(sSubDir) -1; // preserve space for subdir.
  199. TCHAR sFile[MAX_PATH + 256];
  200. HANDLE hToken = NULL;
  201. int iRet = 0;
  202. BOOL bNeedFree = FALSE;
  203. if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_WRITE, &hToken))
  204. goto done;
  205. if (!GetUserProfileDirectory(hToken, &sPath[0], &ulSize)) // Buffer not big enough
  206. {
  207. if (ulSize == sizeof(sPath)-1) // Not because of insufficent space.
  208. goto done;
  209. pPath = (TCHAR*)malloc((ulSize+1+sizeof(sSubDir))*sizeof(TCHAR));
  210. if (!pPath)
  211. {
  212. hr = E_OUTOFMEMORY;
  213. goto done;
  214. }
  215. bNeedFree = TRUE;
  216. if (!GetUserProfileDirectory(hToken, pPath, &ulSize))
  217. {
  218. hr = HRESULT_FROM_WIN32(GetLastError());
  219. goto done;
  220. }
  221. }
  222. if (!pPath)
  223. pPath = sPath;
  224. // Create RCIncidents sub dir
  225. _tcscat(pPath, sSubDir);
  226. iRet = SHCreateDirectoryEx(NULL, pPath, NULL);
  227. if (iRet != ERROR_SUCCESS && iRet != ERROR_ALREADY_EXISTS)
  228. goto done;
  229. // Set variables
  230. iRet = (_tcslen(pPath) + 1) * sizeof(TCHAR);
  231. m_pProfileDir = (TCHAR*)malloc(iRet);
  232. if (!m_pProfileDir)
  233. {
  234. hr = E_OUTOFMEMORY;
  235. goto done;
  236. }
  237. memcpy(m_pProfileDir, pPath, iRet);
  238. m_pIniFile = (TCHAR*)malloc(iRet + (1+sizeof(cstrRCBDYINI))*sizeof(TCHAR));
  239. if (!m_pIniFile)
  240. {
  241. hr = E_OUTOFMEMORY;
  242. goto done;
  243. }
  244. _stprintf(m_pIniFile, _T("%s\\%s"), m_pProfileDir, cstrRCBDYINI);
  245. hr = S_OK;
  246. done:
  247. if (hToken)
  248. CloseHandle(hToken);
  249. if (bNeedFree)
  250. free(pPath);
  251. return hr;
  252. }
  253. */
  254. /*********************************************************
  255. Func:
  256. get_CreatePassword
  257. Abstract:
  258. Create a random string as password
  259. Params:
  260. *********************************************************/
  261. HRESULT CSetting::get_CreatePassword(/*[out, retval]*/ BSTR *pVal)
  262. {
  263. WCHAR szPass[MAX_HELPACCOUNT_PASSWORD + 1];
  264. if (!pVal)
  265. return E_FAIL;
  266. szPass[0] = L'\0';
  267. CreatePassword(szPass);
  268. if (szPass[0] != L'\0')
  269. *pVal = SysAllocString(szPass);
  270. return S_OK;
  271. }
  272. /*********************************************************
  273. Func:
  274. get_GetPropertyInBlob
  275. Abstract:
  276. Get the specified property value in Blob
  277. Params:
  278. bstrBlob: Blob for searching. (ex: 8;PASS=ABC )
  279. bstrName: property name. (ex: "PASS", without '=' char)
  280. *********************************************************/
  281. HRESULT CSetting::get_GetPropertyInBlob(/*[in]*/ BSTR bstrBlob, /*[in]*/ BSTR bstrName, /*[out, retval]*/ BSTR *pVal)
  282. {
  283. HRESULT hRet = S_FALSE;
  284. WCHAR *p1, *p2, *pEnd;
  285. LONG lTotal =0;
  286. size_t lProp = 0;
  287. size_t iNameLen;
  288. if (!bstrBlob || *bstrBlob==L'\0' || !bstrName || *bstrName ==L'\0'|| !pVal)
  289. return FALSE;
  290. iNameLen = wcslen(bstrName);
  291. pEnd = bstrBlob + wcslen(bstrBlob);
  292. p1 = p2 = bstrBlob;
  293. while (1)
  294. {
  295. // get porperty length
  296. while (*p2 != L';' && *p2 != L'\0' && iswdigit(*p2) ) p2++;
  297. if (*p2 != L';')
  298. goto done;
  299. *p2 = L'\0'; // set it to get length
  300. lProp = _wtol(p1);
  301. *p2 = L';'; // revert it back.
  302. // get property string
  303. p1 = ++p2;
  304. while (*p2 != L'=' && *p2 != L'\0' && p2 < p1+lProp) p2++;
  305. if (*p2 != L'=')
  306. goto done;
  307. if ((p2-p1==iNameLen) && (wcsncmp(p1, bstrName, iNameLen)==0) )
  308. {
  309. if (lProp == iNameLen+1) // A=B= case (no value)
  310. goto done;
  311. WCHAR C = *(p2 + lProp-iNameLen);
  312. *(p2 + lProp-iNameLen) = L'\0';
  313. *pVal = SysAllocString(p2+1);
  314. *(p2 + lProp-iNameLen) = C;
  315. hRet = S_OK;
  316. break;
  317. }
  318. // check next property
  319. p2 = p1 = p1 + lProp;
  320. if (p2 > pEnd)
  321. break;
  322. }
  323. done:
  324. return hRet;
  325. }
  326. STDMETHODIMP CSetting::SquishAddress(/*[in]*/ BSTR IP, /*[out, retval]*/ BSTR *pVal)
  327. {
  328. WCHAR szCompIP[30];
  329. if (pVal == NULL)
  330. return E_INVALIDARG;
  331. if (ERROR_SUCCESS == ::SquishAddress((WCHAR*)IP, &szCompIP[0], 29))
  332. {
  333. *pVal = SysAllocString(szCompIP);
  334. }
  335. else
  336. return E_OUTOFMEMORY;
  337. return S_OK;
  338. }
  339. STDMETHODIMP CSetting::ExpandAddress(/*[in]*/ BSTR IP, /*[out, retval]*/ BSTR *pVal)
  340. {
  341. WCHAR szIP[30];
  342. if (pVal == NULL)
  343. return E_INVALIDARG;
  344. if (ERROR_SUCCESS == ::ExpandAddress(&szIP[0], (WCHAR*)IP, 29))
  345. {
  346. *pVal = SysAllocString(szIP);
  347. }
  348. else
  349. return E_OUTOFMEMORY;
  350. return S_OK;
  351. }