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.

421 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. share.cpp
  5. Abstract:
  6. SIS Groveler shared data class
  7. Authors:
  8. John Douceur, 1998
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "all.hxx"
  14. static const _TCHAR map_name[] = _T("Groveler Shared Memory");
  15. static const _TCHAR mutex_name[] = _T("Groveler Shared Memory Mutex");
  16. static const int mutex_timeout = 500;
  17. #define ALIGN_INT64(x) \
  18. (((x+sizeof(__int64)-1)/sizeof(__int64))*sizeof(__int64))
  19. SharedData::SharedData(
  20. int num_records,
  21. _TCHAR **drive_names)
  22. {
  23. ASSERT(this != 0);
  24. ASSERT(num_records <= max_shared_data_records);
  25. map_ok = false;
  26. mutex = 0;
  27. map_handle = 0;
  28. map_address = 0;
  29. shared_num_records = 0;
  30. shared_records = 0;
  31. security_identifier = 0;
  32. access_control_list = 0;
  33. ZeroMemory(&security_attributes, sizeof(SECURITY_ATTRIBUTES));
  34. ZeroMemory(&security_descriptor, sizeof(SECURITY_DESCRIPTOR));
  35. //
  36. // Initailize a Security descriptor so we can setup secure access
  37. // to a shared file.
  38. //
  39. security_attributes.bInheritHandle = FALSE;
  40. security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  41. security_attributes.lpSecurityDescriptor = (void *)&security_descriptor;
  42. BOOL success = InitializeSecurityDescriptor(&security_descriptor,
  43. SECURITY_DESCRIPTOR_REVISION);
  44. if (!success)
  45. {
  46. DWORD err = GetLastError();
  47. PRINT_DEBUG_MSG((
  48. _T("GROVELER: InitializeSecurityDescriptor() failed with error %d\n"), err));
  49. return;
  50. }
  51. SID_IDENTIFIER_AUTHORITY sid_authority = SECURITY_NT_AUTHORITY;
  52. success = AllocateAndInitializeSid(
  53. &sid_authority,
  54. 2,
  55. SECURITY_BUILTIN_DOMAIN_RID,
  56. DOMAIN_ALIAS_RID_ADMINS,
  57. 0,
  58. 0,
  59. 0,
  60. 0,
  61. 0,
  62. 0,
  63. &security_identifier);
  64. if (!success)
  65. {
  66. DWORD err = GetLastError();
  67. PRINT_DEBUG_MSG((
  68. _T("GROVELER: AllocateAndInitializeSid() failed with error %d\n"), err));
  69. return;
  70. }
  71. //
  72. // Create ACL
  73. //
  74. DWORD acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
  75. + GetLengthSid(security_identifier);
  76. access_control_list = (PACL)new BYTE[acl_size];
  77. success = InitializeAcl(
  78. access_control_list,
  79. acl_size,
  80. ACL_REVISION);
  81. if (!success)
  82. {
  83. DWORD err = GetLastError();
  84. PRINT_DEBUG_MSG((_T("GROVELER: InitializeAcl() failed with error %d\n"), err));
  85. return;
  86. }
  87. success = AddAccessAllowedAce(
  88. access_control_list,
  89. ACL_REVISION,
  90. GENERIC_ALL,
  91. security_identifier);
  92. if (!success)
  93. {
  94. DWORD err = GetLastError();
  95. PRINT_DEBUG_MSG((_T("GROVELER: AddAccessAllowedAce() failed with error %d\n"),
  96. err));
  97. return;
  98. }
  99. success = SetSecurityDescriptorDacl(
  100. &security_descriptor,
  101. TRUE,
  102. access_control_list,
  103. FALSE);
  104. if (!success)
  105. {
  106. DWORD err = GetLastError();
  107. PRINT_DEBUG_MSG((_T("GROVELER: SetSecurityDescriptorDacl() failed with error %d\n"),
  108. err));
  109. return;
  110. }
  111. //
  112. // Create a named mutex
  113. //
  114. mutex = new NamedMutex(mutex_name, &security_attributes);
  115. ASSERT(mutex != 0);
  116. //
  117. // Calcualte size of mapped file
  118. //
  119. int map_size = ALIGN_INT64(sizeof(int))
  120. + ALIGN_INT64(max_shared_data_records * sizeof(SharedDataRecord));
  121. bool ok = mutex->acquire(mutex_timeout);
  122. if (!ok)
  123. {
  124. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n")));
  125. return;
  126. }
  127. //
  128. // Create the mapped file. Note that it will be backed by system paging
  129. // files.
  130. //
  131. map_handle = CreateFileMapping((HANDLE)-1, &security_attributes,
  132. PAGE_READWRITE, 0, map_size, map_name);
  133. DWORD map_error = GetLastError();
  134. if (map_handle == 0)
  135. {
  136. PRINT_DEBUG_MSG((_T("GROVELER: CreateFileMapping() failed with error %d\n"),
  137. map_error));
  138. return;
  139. }
  140. ASSERT(map_error == NO_ERROR || map_error == ERROR_ALREADY_EXISTS);
  141. //
  142. // Map a view for this file
  143. //
  144. map_address =
  145. MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS, 0, 0, map_size);
  146. if (map_address == 0)
  147. {
  148. DWORD err = GetLastError();
  149. PRINT_DEBUG_MSG((_T("GROVELER: MapViewOfFile() failed with error %d\n"), err));
  150. return;
  151. }
  152. shared_num_records = (int *)map_address;
  153. shared_records =
  154. (SharedDataRecord *)ALIGN_INT64((DWORD_PTR)(shared_num_records + 1));
  155. local_num_records = __max(num_records, 0);
  156. ZeroMemory(local_records, max_shared_data_records * sizeof(SharedDataRecord));
  157. ASSERT(local_num_records == 0 || drive_names != 0);
  158. for (int index = 0; index < local_num_records; index++)
  159. {
  160. local_records[index].driveName = drive_names[index];
  161. }
  162. map_ok = true;
  163. if (num_records >= 0 || map_error == NO_ERROR)
  164. {
  165. bool ok = send_values();
  166. }
  167. ok = mutex->release();
  168. if (!ok)
  169. {
  170. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n")));
  171. }
  172. }
  173. SharedData::~SharedData()
  174. {
  175. ASSERT(this != 0);
  176. ASSERT(mutex != 0);
  177. delete mutex;
  178. mutex = 0;
  179. if (map_address != 0)
  180. {
  181. int ok = UnmapViewOfFile(map_address);
  182. if (!ok)
  183. {
  184. DWORD err = GetLastError();
  185. PRINT_DEBUG_MSG((_T("GROVELER: UnmapViewOfFile() failed with error %d\n"),
  186. err));
  187. }
  188. map_address = 0;
  189. }
  190. if (map_handle != 0)
  191. {
  192. int ok = CloseHandle(map_handle);
  193. if (!ok)
  194. {
  195. DWORD err = GetLastError();
  196. PRINT_DEBUG_MSG((_T("GROVELER: CloseHandle() failed with error %d\n"), err));
  197. }
  198. map_handle = 0;
  199. }
  200. if (security_identifier != 0)
  201. {
  202. FreeSid(security_identifier);
  203. security_identifier = 0;
  204. }
  205. if (access_control_list != 0)
  206. {
  207. delete[] access_control_list;
  208. access_control_list = 0;
  209. }
  210. }
  211. int
  212. SharedData::count_of_records() const
  213. {
  214. ASSERT(this != 0);
  215. return local_num_records;
  216. }
  217. //_TCHAR
  218. //SharedData::drive_letter(
  219. // int record_index) const
  220. //{
  221. // ASSERT(this != 0);
  222. // ASSERT(record_index >= 0);
  223. // ASSERT(record_index < max_shared_data_records);
  224. // ASSERT(record_index < local_num_records);
  225. // return local_records[record_index].drive_letter;
  226. //}
  227. __int64
  228. SharedData::get_value(
  229. int record_index,
  230. SharedDataField field)
  231. {
  232. ASSERT(this != 0);
  233. ASSERT(record_index >= 0);
  234. ASSERT(record_index < max_shared_data_records);
  235. ASSERT(record_index < local_num_records);
  236. ASSERT(field >= 0);
  237. ASSERT(field < num_shared_data_fields);
  238. return local_records[record_index].fields[field];
  239. }
  240. void
  241. SharedData::set_value(
  242. int record_index,
  243. SharedDataField field,
  244. __int64 value)
  245. {
  246. ASSERT(this != 0);
  247. ASSERT(record_index >= 0);
  248. ASSERT(record_index < max_shared_data_records);
  249. ASSERT(record_index < local_num_records);
  250. ASSERT(field >= 0);
  251. ASSERT(field < num_shared_data_fields);
  252. local_records[record_index].fields[field] = value;
  253. }
  254. void
  255. SharedData::increment_value(
  256. int record_index,
  257. SharedDataField field,
  258. __int64 value)
  259. {
  260. ASSERT(this != 0);
  261. ASSERT(record_index >= 0);
  262. ASSERT(record_index < max_shared_data_records);
  263. ASSERT(record_index < local_num_records);
  264. ASSERT(field >= 0);
  265. ASSERT(field < num_shared_data_fields);
  266. local_records[record_index].fields[field] += value;
  267. }
  268. bool
  269. SharedData::send_values()
  270. {
  271. ASSERT(this != 0);
  272. if (map_ok)
  273. {
  274. bool ok = mutex->acquire(mutex_timeout);
  275. if (ok)
  276. {
  277. ASSERT(shared_num_records != 0);
  278. *shared_num_records = local_num_records;
  279. ASSERT(shared_records != 0);
  280. ASSERT(local_records != 0);
  281. for (int index = 0; index < local_num_records; index++)
  282. {
  283. shared_records[index] = local_records[index];
  284. }
  285. ok = mutex->release();
  286. if (!ok)
  287. {
  288. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n")));
  289. }
  290. }
  291. else
  292. {
  293. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n")));
  294. }
  295. return ok;
  296. }
  297. else
  298. {
  299. return false;
  300. }
  301. }
  302. bool
  303. SharedData::receive_values()
  304. {
  305. ASSERT(this != 0);
  306. if (map_ok)
  307. {
  308. bool ok = mutex->acquire(mutex_timeout);
  309. if (ok)
  310. {
  311. ASSERT(shared_num_records != 0);
  312. local_num_records = *shared_num_records;
  313. ASSERT(shared_records != 0);
  314. ASSERT(local_records != 0);
  315. for (int index = 0; index < local_num_records; index++)
  316. {
  317. local_records[index] = shared_records[index];
  318. }
  319. ok = mutex->release();
  320. if (!ok)
  321. {
  322. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n")));
  323. }
  324. }
  325. else
  326. {
  327. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n")));
  328. }
  329. return ok;
  330. }
  331. else
  332. {
  333. return false;
  334. }
  335. }
  336. bool
  337. SharedData::extract_values(
  338. int *num_records,
  339. SharedDataRecord *records)
  340. {
  341. ASSERT(this != 0);
  342. if (map_ok)
  343. {
  344. bool ok = mutex->acquire(mutex_timeout);
  345. if (ok)
  346. {
  347. ASSERT(shared_num_records != 0);
  348. ASSERT(num_records != 0);
  349. *num_records = *shared_num_records;
  350. ASSERT(shared_records != 0);
  351. ASSERT(records != 0);
  352. for (int index = 0; index < *num_records; index++)
  353. {
  354. records[index] = shared_records[index];
  355. }
  356. ok = mutex->release();
  357. if (!ok)
  358. {
  359. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::release() failed\n")));
  360. }
  361. }
  362. else
  363. {
  364. PRINT_DEBUG_MSG((_T("GROVELER: Mutex::acquire() failed\n")));
  365. }
  366. return ok;
  367. }
  368. else
  369. {
  370. return false;
  371. }
  372. }