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.

352 lines
10 KiB

  1. #include "flock.hxx"
  2. // #include <resource.h>
  3. #include <cache.hxx>
  4. #undef inet_ntoa
  5. #undef inet_addr
  6. #undef gethostname
  7. #undef gethostbyname
  8. #undef gethostbyaddr
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #ifdef sunos5
  14. extern "C" int gethostname(char*,int);
  15. #endif
  16. extern HANDLE MwOpenProcess(pid_t, BOOL);
  17. extern "C" MwAtExit(void (*f)(void));
  18. //locally used functions
  19. int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len);
  20. off_t lock_test(int fd, int type, off_t *offset, int whence, off_t *len);
  21. #define REG_READONLYCACHE TEXT("Software\\Microsoft\\Internet Explorer\\Unix\\ReadOnlyCacheWarning")
  22. #define REG_READONLYCACHEKEY TEXT("ShowCacheWarning")
  23. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  24. #define SECONDSINDAY 86400
  25. #define REG_READONLYCACHE TEXT("Software\\Microsoft\\Internet Explorer\\Unix\\ReadOnlyCacheWarning")
  26. #define REG_READONLYCACHEKEY TEXT("ShowCacheWarning")
  27. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  28. #define SECONDSINDAY 86400
  29. // lock region relative to whence starting at offset upto len bytes
  30. int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) {
  31. struct flock lock;
  32. lock.l_type = type; //F_RDLCK, F_WRLCK, F_UNLCK
  33. lock.l_start = offset; //byte offset, relative to l_whence
  34. lock.l_whence = whence; //SEEK_SET, SEEK_CUR, SEEK_END
  35. lock.l_len = len; //#bytes (0 means to EOF)
  36. return( fcntl(fd, cmd, &lock) );
  37. }
  38. // test region for locks relative to whence starting at offset for len bytes
  39. off_t lock_test(int fd, int type, off_t *offset, int whence, off_t *len) {
  40. struct flock lock;
  41. lock.l_type = type; //F_RDLCK, F_WRLCK, F_UNLCK
  42. lock.l_start = *offset; //byte offset, relative to l_whence
  43. lock.l_whence = whence; //SEEK_SET, SEEK_CUR, SEEK_END
  44. lock.l_len = *len; // #bytes (0 means to EOF)
  45. if (fcntl(fd, F_GETLK, &lock) < 0)
  46. return(-1);
  47. if (lock.l_type == F_UNLCK)
  48. return(0); // nobody has lock in this region
  49. else if (lock.l_type == F_RDLCK) {
  50. *offset = lock.l_start;
  51. *len = lock.l_len;
  52. return(lock.l_start); // byte offset of host with read lock
  53. } else { // dont support extended semantics of
  54. return(-1); // write lock yet
  55. }
  56. }
  57. extern "C" void unixCleanupWininetCacheLockFile()
  58. {
  59. // if(!g_ReadOnlyCaches)
  60. //unlink(szLockDBName);
  61. }
  62. BOOL CreateAtomicCacheLockFile(BOOL *pfReadOnlyCaches, char **pszLockingHost)
  63. {
  64. int fdlockdbf, fdlock, envLen, hostbynameerr;
  65. off_t IPOffset=0, IPLen=0, ownIPOffset, ownIPLen;
  66. char *hostname, hostbynamebuf[512];
  67. char szLockFileName[MAX_PATH+1], szLockDBName[MAX_PATH+1];
  68. struct hostent hostbynameresult;
  69. #ifdef ux10
  70. struct hostent_data hostentdata;
  71. #endif
  72. char *pEnv = getenv("MWUSER_DIRECTORY");
  73. /* Don't process the ielock file for Mainwin Lite programs */
  74. if (MwIsInitLite())
  75. goto Cleanup;
  76. if (pEnv == 0)
  77. return FALSE;
  78. envLen = strlen(pEnv);
  79. if (envLen > MAX_PATH-256)
  80. return FALSE;
  81. strcpy(szLockFileName, pEnv);
  82. if (szLockFileName[envLen-1] != '/') {
  83. szLockFileName[envLen] = '/';
  84. szLockFileName[envLen+1] = 0x00;
  85. }
  86. strcpy(szLockDBName, pEnv);
  87. if (szLockDBName[envLen-1] != '/') {
  88. szLockDBName[envLen] = '/';
  89. szLockDBName[envLen+1] = 0x00;
  90. }
  91. strcat(szLockFileName, LF);
  92. strcat(szLockDBName, LOCKDBF);
  93. hostname = (char *)malloc(256*sizeof(char));
  94. if ((hostname == NULL) || (gethostname(hostname, 256) == -1)) {
  95. *pfReadOnlyCaches = TRUE;
  96. return FALSE;
  97. }
  98. #ifdef sunos5
  99. if (!(gethostbyname_r(hostname, &hostbynameresult, hostbynamebuf,
  100. sizeof(hostbynamebuf), &hostbynameerr))) {
  101. *pfReadOnlyCaches = TRUE;
  102. return FALSE;
  103. }
  104. #endif
  105. #ifdef ux10
  106. if (gethostbyname_r(hostname, &hostbynameresult, &hostentdata) < 0) {
  107. *pfReadOnlyCaches = TRUE;
  108. return FALSE;
  109. }
  110. #endif
  111. struct in_addr *ptr = (struct in_addr *)*hostbynameresult.h_addr_list;
  112. ownIPOffset = inet_netof(*ptr);
  113. ownIPLen = inet_lnaof(*ptr);
  114. if ((fdlock = open(szLockFileName, O_WRONLY|O_CREAT|O_EXCL, FILE_MODE)) < 0) {
  115. if (errno == EEXIST) {
  116. if ((fdlock = open(szLockFileName, O_WRONLY)) < 0) {
  117. *pfReadOnlyCaches = TRUE;
  118. return FALSE;
  119. }
  120. } else {
  121. *pfReadOnlyCaches = TRUE;
  122. return FALSE;
  123. }
  124. }
  125. if (writew_lock(fdlock, 0, SEEK_SET, 0) < 0) {
  126. *pfReadOnlyCaches = TRUE;
  127. return FALSE;
  128. }
  129. /*under this lock, now do all the examination of szLockDBName*/
  130. if ((fdlockdbf = open(szLockDBName, O_RDWR|O_CREAT|O_EXCL, FILE_MODE)) < 0) {
  131. if (errno == EEXIST) {
  132. if ((fdlockdbf = open(szLockDBName, O_RDWR)) < 0) {
  133. *pfReadOnlyCaches = TRUE;
  134. un_lock(fdlock, 0, SEEK_SET, 0);
  135. return FALSE;
  136. }
  137. } else {
  138. *pfReadOnlyCaches = TRUE;
  139. un_lock(fdlock, 0, SEEK_SET, 0);
  140. return FALSE;
  141. }
  142. }
  143. /* check entire file for locking */
  144. if ((can_writelock(fdlockdbf, &IPOffset, SEEK_SET, &IPLen)) >= 0) {
  145. if ((IPOffset == 0) || ((IPOffset == ownIPOffset) && (IPLen == ownIPLen))){
  146. // either no IE writing to cache or IE on own host writing to cache
  147. // (IP address is identical)..either way we have write access
  148. *pfReadOnlyCaches = FALSE;
  149. *pszLockingHost = hostname;
  150. //lock at "network part" position for "host part" bytes
  151. read_lock(fdlockdbf, ownIPOffset, SEEK_SET, ownIPLen);
  152. un_lock(fdlock, 0, SEEK_SET, 0);
  153. return TRUE;
  154. } else {
  155. //some other host writing to cache
  156. *pfReadOnlyCaches = TRUE;
  157. u_long addr = inet_addr(inet_ntoa(inet_makeaddr(IPOffset, IPLen)));
  158. struct hostent * hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  159. if (!hp)
  160. ; //cant find hostname from offset & length of locked bytes..
  161. else
  162. *pszLockingHost = hp->h_name;
  163. un_lock(fdlock, 0, SEEK_SET, 0);
  164. return TRUE;
  165. }
  166. } else {
  167. //can_writelock returned -1 with some fcntl error
  168. *pfReadOnlyCaches = TRUE;
  169. un_lock(fdlock, 0, SEEK_SET, 0);
  170. return FALSE;
  171. }
  172. Cleanup:
  173. return TRUE;
  174. }
  175. BOOL DeleteAtomicCacheLockFile()
  176. {
  177. /* Don't process for MainWin Lite programs */
  178. /* Right now, the code below does not make sense because all
  179. * we do is return TRUE. So, commenting out this code for now.
  180. */
  181. #if 0
  182. if (MwIsInitLite())
  183. goto Cleanup;
  184. Cleanup:
  185. #endif /* 0 */
  186. //unlink(szLockDBName);
  187. return TRUE;
  188. }
  189. #if 0 // Back out till we get a consensus on this
  190. BOOL CALLBACK ReadOnlyCache_DlgProc(HWND hDlg,
  191. UINT uMsg,
  192. WPARAM wParam,
  193. LPARAM lParam) {
  194. switch (uMsg) {
  195. case WM_INITDIALOG:
  196. {
  197. LPTSTR lpszMessageStr = (LPTSTR)lParam;
  198. TCHAR pszText[MAX_PATH];
  199. TCHAR pszFormattedText[MAX_PATH];
  200. if (lpszMessageStr)
  201. {
  202. if (LoadString(GlobalDllHandle,
  203. IDS_READONLYCACHE,
  204. pszText,
  205. ARRAYSIZE(pszText))) {
  206. wsprintf(pszFormattedText,pszText, lpszMessageStr);
  207. SetDlgItemText(hDlg, IDC_READONLYCACHE, pszFormattedText);
  208. }
  209. }
  210. SetFocus(GetDlgItem(hDlg, IDOK));
  211. }
  212. break;
  213. case WM_COMMAND:
  214. switch (LOWORD(wParam))
  215. {
  216. case IDOK:
  217. {
  218. if (IsDlgButtonChecked(hDlg, IDC_DONT_WANT_WARNING))
  219. EndDialog(hDlg, 1);
  220. else
  221. EndDialog(hDlg, 0);
  222. break;
  223. }
  224. default:
  225. return FALSE;
  226. }
  227. return TRUE;
  228. case WM_CLOSE:
  229. {
  230. if (IsDlgButtonChecked(hDlg, IDC_DONT_WANT_WARNING))
  231. EndDialog(hDlg, 1);
  232. else
  233. EndDialog(hDlg, 0);
  234. }
  235. return TRUE;
  236. }
  237. return FALSE;
  238. }
  239. void ShowReadOnlyCacheDialog(char* pszHostName) {
  240. DWORD dwError = E_FAIL;
  241. HKEY hKey = NULL;
  242. DWORD dwValue = 0;
  243. DWORD dwValueType;
  244. DWORD dwValueSize = sizeof(DWORD);
  245. if ((dwError = REGOPENKEYEX(HKEY_CURRENT_USER,
  246. REG_READONLYCACHE,
  247. 0,
  248. KEY_READ|KEY_WRITE,
  249. &hKey)) != ERROR_SUCCESS)
  250. {
  251. goto Cleanup;
  252. }
  253. if ((dwError = RegQueryValueEx(hKey,
  254. REG_READONLYCACHEKEY,
  255. 0,
  256. &dwValueType,
  257. (LPBYTE)&dwValue,
  258. &dwValueSize)) != ERROR_SUCCESS)
  259. {
  260. goto Cleanup;
  261. }
  262. if (dwValue)
  263. {
  264. int fRet = 0;
  265. if ((fRet = DialogBoxParam(GlobalDllHandle,
  266. MAKEINTRESOURCE(IDD_READONLYCACHE),
  267. NULL,
  268. ReadOnlyCache_DlgProc,
  269. (LPARAM)pszHostName)) < 0)
  270. {
  271. goto Cleanup;
  272. }
  273. /*
  274. * we are here, because the registry told us to show this dialog.
  275. * now, we check if fRet == TRUE, in which case we don't show this
  276. * dialog in the future. And, we update the registry.
  277. */
  278. if (fRet == 1) {
  279. /* ShowCacheWarning will be set to False in the registry */
  280. dwValue = 0;
  281. /*
  282. * we don't check for the error here, because we close the key next
  283. * and if we did not save successfully, we will show this dialog again
  284. */
  285. RegSetValueEx(hKey,
  286. REG_READONLYCACHEKEY,
  287. 0,
  288. dwValueType,
  289. (LPBYTE)&dwValue,
  290. dwValueSize);
  291. }
  292. }
  293. Cleanup:
  294. if (hKey)
  295. REGCLOSEKEY(hKey);
  296. return;
  297. }
  298. #endif