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.

678 lines
19 KiB

  1. /*++
  2. Copyright (c) 1993/4 Microsoft Corporation
  3. Module Name:
  4. Locks.c
  5. Abstract:
  6. This module implements the routines for the NetWare
  7. 16 bit support to perform the synchonization api's
  8. Author:
  9. Colin Watson [ColinW] 07-Dec-1993
  10. Revision History:
  11. --*/
  12. #include "Procs.h"
  13. UCHAR LockMode = 0;
  14. BOOLEAN Tickle[MC];
  15. NTSTATUS
  16. Sem(
  17. UCHAR Function,
  18. UCHAR Connection
  19. );
  20. VOID
  21. Locks(
  22. USHORT Command
  23. )
  24. /*++
  25. Routine Description:
  26. Implements all the locking operations
  27. Arguments:
  28. Command - supplies Applications AX.
  29. Return Value:
  30. Return status.
  31. --*/
  32. {
  33. UCHAR Function = Command & 0x00ff;
  34. USHORT Operation = Command & 0xff00;
  35. CONN_INDEX Connection;
  36. NTSTATUS status = STATUS_SUCCESS;
  37. PUCHAR Request;
  38. ULONG RequestLength;
  39. WORD Timeout;
  40. if ( Operation != 0xCF00) {
  41. //
  42. // Connection does not need to be initialised for CF00 because
  43. // we have to loop through all connections. Its harmful because
  44. // a CF00 is created during ProcessExit(). If we call selectconnection
  45. // and there is no server available this will make process exit
  46. // really slow.
  47. //
  48. Connection = SelectConnectionInCWD();
  49. if (Connection == 0xff) {
  50. setAL(0xff);
  51. return;
  52. }
  53. if ( ServerHandles[Connection] == NULL ) {
  54. status = OpenConnection( Connection );
  55. if (!NT_SUCCESS(status)) {
  56. setAL((UCHAR)RtlNtStatusToDosError(status));
  57. return;
  58. }
  59. }
  60. }
  61. switch ( Operation ) {
  62. case 0xBC00: // Log physical record
  63. status = NwlibMakeNcp(
  64. GET_NT_HANDLE(),
  65. NWR_ANY_HANDLE_NCP(0x1A),
  66. 17, // RequestSize
  67. 0, // ResponseSize
  68. "b_wwwww",
  69. Function,
  70. 6, // Leave space for NetWare handle
  71. getCX(),getDX(),
  72. getSI(),getDI(),
  73. getBP());
  74. break;
  75. case 0xBD00: // Physical Unlock
  76. status = NwlibMakeNcp(
  77. GET_NT_HANDLE(),
  78. NWR_ANY_HANDLE_NCP(0x1C),
  79. 15, // RequestSize
  80. 0, // ResponseSize
  81. "b_wwww",
  82. Function,
  83. 6, // Leave space for NetWare handle
  84. getCX(),getDX(),
  85. getSI(),getDI());
  86. break;
  87. case 0xBE00: // Clear physical record
  88. status = NwlibMakeNcp(
  89. GET_NT_HANDLE(),
  90. NWR_ANY_HANDLE_NCP(0x1E),
  91. 15, // RequestSize
  92. 0, // ResponseSize
  93. "b_wwww",
  94. Function,
  95. 6, // Leave space for NetWare handle
  96. getCX(),getDX(),
  97. getSI(),getDI());
  98. break;
  99. case 0xC200: // Physical Lock set
  100. status = NwlibMakeNcp(
  101. ServerHandles[Connection],
  102. NWR_ANY_F2_NCP(0x1B),
  103. 3, // RequestSize
  104. 0, // ResponseSize
  105. "bw",
  106. Function,
  107. getBP());
  108. break;
  109. case 0xC300: // Release Physical Record Set
  110. status = NwlibMakeNcp(
  111. ServerHandles[Connection],
  112. NWR_ANY_F2_NCP(0x1D),
  113. 0, // RequestSize
  114. 0, // ResponseSize
  115. "");
  116. break;
  117. case 0xC400: // Clear Physical Record Set
  118. status = NwlibMakeNcp(
  119. ServerHandles[Connection],
  120. NWR_ANY_F2_NCP(0x1F), // Clear Physical Record Set
  121. 0, // RequestSize
  122. 0, // ResponseSize
  123. "");
  124. break;
  125. case 0xC500: // All Semaphore operations
  126. status = Sem(Function, Connection);
  127. break;
  128. case 0xC600: // Set/Get Lock mode
  129. if (Function != 2) {
  130. LockMode = Function;
  131. }
  132. setAL(LockMode);
  133. return; // avoid setting AL to status at the end of this routine
  134. break;
  135. case 0xCB00: // Lock File Set
  136. if (LockMode == 0) {
  137. if (getDL()) {
  138. Timeout = 0xffff;
  139. } else {
  140. Timeout = 0;
  141. }
  142. } else {
  143. Timeout = getBP();
  144. }
  145. for (Connection = 0; Connection < MC; Connection++) {
  146. if (Tickle[Connection]) {
  147. status = NwlibMakeNcp(
  148. ServerHandles[Connection],
  149. NWR_ANY_F2_NCP(0x04),
  150. 2, // RequestSize
  151. 0, // ResponseSize
  152. "w",
  153. Timeout);
  154. if (!NT_SUCCESS(status)) {
  155. break;
  156. }
  157. }
  158. }
  159. break;
  160. case 0xCD00: // Release File Set
  161. case 0xCF00: // Clear File Set
  162. for (Connection = 0; Connection < MC; Connection++) {
  163. if (Tickle[Connection]) {
  164. status = NwlibMakeNcp(
  165. ServerHandles[Connection],
  166. (Operation == 0xCD00) ? NWR_ANY_F2_NCP(0x06): NWR_ANY_F2_NCP(0x08),
  167. 0, // RequestSize
  168. 0, // ResponseSize
  169. "");
  170. if (!NT_SUCCESS(status)) {
  171. break;
  172. }
  173. if (Operation == 0xCF00) {
  174. Tickle[Connection] = FALSE;
  175. }
  176. }
  177. }
  178. break;
  179. case 0xD000: // Log Logical Record
  180. Request = GetVDMPointer (
  181. (ULONG)((getDS() << 16)|getDX()),
  182. sizeof(UCHAR),
  183. IS_PROTECT_MODE());
  184. RequestLength = Request[0] + 1;
  185. Request = GetVDMPointer (
  186. (ULONG)((getDS() << 16)|getDX()),
  187. RequestLength,
  188. IS_PROTECT_MODE());
  189. status = NwlibMakeNcp(
  190. ServerHandles[Connection],
  191. NWR_ANY_F2_NCP(0x09),
  192. RequestLength + 5, // RequestSize
  193. 0, // ResponseSize
  194. "bwbr",
  195. (LockMode) ? Function : 0,
  196. (LockMode) ? getBP() : 0,
  197. RequestLength,
  198. Request, RequestLength );
  199. break;
  200. case 0xD100: // Lock Logical Record Set
  201. if (LockMode == 0) {
  202. if (getDL()) {
  203. Timeout = 0xffff;
  204. } else {
  205. Timeout = 0;
  206. }
  207. } else {
  208. Timeout = getBP();
  209. }
  210. status = NwlibMakeNcp(
  211. ServerHandles[Connection],
  212. NWR_ANY_F2_NCP(0x0A),
  213. 3, // RequestSize
  214. 0, // ResponseSize
  215. "bw",
  216. (LockMode) ? Function : 0,
  217. Timeout);
  218. break;
  219. case 0xD200: // Release File
  220. case 0xD400: // Clear Logical Record
  221. Request = GetVDMPointer (
  222. (ULONG)((getDS() << 16)|getDX()),
  223. sizeof(UCHAR),
  224. IS_PROTECT_MODE());
  225. RequestLength = Request[0]+1;
  226. Request = GetVDMPointer (
  227. (ULONG)((getDS() << 16)|getDX()),
  228. RequestLength,
  229. IS_PROTECT_MODE());
  230. status = NwlibMakeNcp(
  231. ServerHandles[Connection],
  232. (Operation == 0xD200) ? NWR_ANY_F2_NCP(0x0C) :
  233. NWR_ANY_F2_NCP(0x0B),
  234. RequestLength+1,
  235. 0, // ResponseSize
  236. "br",
  237. RequestLength,
  238. Request, RequestLength );
  239. break;
  240. case 0xD300:
  241. status = NwlibMakeNcp(
  242. ServerHandles[Connection],
  243. NWR_ANY_F2_NCP(0x13),
  244. 0, // RequestSize
  245. 0, // ResponseSize
  246. "");
  247. break;
  248. case 0xD500: // Clear Logical Record Set
  249. status = NwlibMakeNcp(
  250. ServerHandles[Connection],
  251. NWR_ANY_F2_NCP(0x0E),
  252. 0, // RequestSize
  253. 0, // ResponseSize
  254. "");
  255. break;
  256. case 0xEB00: // Log File
  257. case 0xEC00: // Release File
  258. case 0xED00: // Clear File
  259. {
  260. UCHAR DirHandle;
  261. HANDLE Win32DirectoryHandle = 0;
  262. PUCHAR ptr;
  263. Request = GetVDMPointer (
  264. (ULONG)((getDS() << 16)|getDX()),
  265. 256 * sizeof(UCHAR),
  266. IS_PROTECT_MODE());
  267. RequestLength = strlen(Request);
  268. // Find DirHandle
  269. ptr = Request;
  270. while ( (*ptr != 0) &&
  271. (!IS_ASCII_PATH_SEPARATOR(*ptr)) &&
  272. (*ptr != ':' )) {
  273. ptr++;
  274. }
  275. if (IS_ASCII_PATH_SEPARATOR(*ptr)) {
  276. int ServerNameLength = (int) (ptr - Request);
  277. PUCHAR scanptr = ptr;
  278. //
  279. // Make sure there is a ":" further up the name otherwise
  280. // we could confuse foo\bar.txt with a server called foo
  281. //
  282. while ( (*scanptr != 0) &&
  283. (*scanptr != ':' )) {
  284. scanptr++;
  285. }
  286. if (*scanptr) {
  287. //
  288. // Name is of the form server\sys:foo\bar.txt
  289. // set connection appropriately.
  290. //
  291. for (Connection = 0; Connection < MC ; Connection++ ) {
  292. //
  293. // Look for server foo avoiding foobar.
  294. //
  295. if ((pNwDosTable->ConnectionIdTable[Connection].ci_InUse ==
  296. IN_USE) &&
  297. (!memcmp( pNwDosTable->ServerNameTable[Connection],
  298. Request,
  299. ServerNameLength)) &&
  300. (pNwDosTable->ServerNameTable[Connection][ServerNameLength] ==
  301. '\0')) {
  302. break; // Connection is the correct server
  303. }
  304. }
  305. //
  306. // Move Request to after the seperator and ptr to the ":"
  307. //
  308. RequestLength -= (ULONG) (ptr + sizeof(UCHAR) - Request);
  309. Request = ptr + sizeof(UCHAR);
  310. ptr = scanptr;
  311. }
  312. }
  313. if (*ptr) {
  314. //
  315. // Name of form "sys:foo\bar.txt" this gives the server
  316. // all the information required.
  317. //
  318. DirHandle = 0;
  319. if (Request[1] == ':') {
  320. UCHAR Drive = tolower(Request[0])-'a';
  321. //
  322. // Its a normal (redirected) drive k:foo\bar.txt.
  323. // Use the drive tables to give the connection and handle.
  324. //
  325. Connection = pNwDosTable->DriveIdTable[ Drive ] - 1;
  326. DirHandle = pNwDosTable->DriveHandleTable[Drive];
  327. if (DirHandle == 0) {
  328. DirHandle = (UCHAR)GetDirectoryHandle2(Drive);
  329. }
  330. Request += 2; // skip "k:"
  331. RequestLength -= 2;
  332. }
  333. } else {
  334. WCHAR Curdir[256];
  335. //
  336. // Name of form "foo\bar.txt"
  337. //
  338. GetCurrentDirectory(sizeof(Curdir) / sizeof(WCHAR), Curdir);
  339. Win32DirectoryHandle =
  340. CreateFileW( Curdir,
  341. 0,
  342. FILE_SHARE_READ | FILE_SHARE_WRITE,
  343. NULL,
  344. OPEN_EXISTING,
  345. FILE_FLAG_BACKUP_SEMANTICS,
  346. 0);
  347. if (Win32DirectoryHandle != INVALID_HANDLE_VALUE) {
  348. DWORD BytesReturned;
  349. if ( DeviceIoControl(
  350. Win32DirectoryHandle,
  351. IOCTL_NWR_RAW_HANDLE,
  352. NULL,
  353. 0,
  354. (PUCHAR)&DirHandle,
  355. sizeof(DirHandle),
  356. &BytesReturned,
  357. NULL ) == FALSE ) {
  358. CloseHandle( Win32DirectoryHandle );
  359. setAL(0xff);
  360. return;
  361. }
  362. } else {
  363. setAL(0xff);
  364. return;
  365. }
  366. }
  367. if (Operation == 0xEB00) {
  368. status = NwlibMakeNcp(
  369. ServerHandles[Connection],
  370. NWR_ANY_F2_NCP(0x03),
  371. RequestLength + 5,
  372. 0, // ResponseSize
  373. "bbwbr",
  374. DirHandle,
  375. (LockMode) ? Function : 0,
  376. (LockMode) ? getBP() : 0,
  377. RequestLength,
  378. Request, RequestLength );
  379. Tickle[Connection] = TRUE;
  380. } else {
  381. status = NwlibMakeNcp(
  382. ServerHandles[Connection],
  383. (Operation == 0xEC00 ) ?
  384. NWR_ANY_F2_NCP(0x07) :
  385. NWR_ANY_F2_NCP(0x05),
  386. RequestLength + 2,
  387. 0, // ResponseSize
  388. "bbr",
  389. DirHandle,
  390. RequestLength,
  391. Request, RequestLength );
  392. }
  393. if (Win32DirectoryHandle) {
  394. CloseHandle( Win32DirectoryHandle );
  395. }
  396. }
  397. break;
  398. }
  399. if (!NT_SUCCESS(status)) {
  400. setAL((UCHAR)RtlNtStatusToDosError(status));
  401. return;
  402. } else {
  403. setAL(0);
  404. }
  405. }
  406. VOID
  407. InitLocks(
  408. VOID
  409. )
  410. /*++
  411. Routine Description:
  412. Reset the Tickle internal variables
  413. Arguments:
  414. None.
  415. Return Value:
  416. None.
  417. --*/
  418. {
  419. ZeroMemory( Tickle, sizeof(Tickle));
  420. }
  421. VOID
  422. ResetLocks(
  423. VOID
  424. )
  425. /*++
  426. Routine Description:
  427. Reset the Locks for the current VDM. Called during process exit.
  428. Arguments:
  429. None.
  430. Return Value:
  431. None.
  432. --*/
  433. {
  434. Locks(0xCF00); // Clear all File sets.
  435. }
  436. NTSTATUS
  437. Sem(
  438. UCHAR Function,
  439. UCHAR Connection
  440. )
  441. /*++
  442. Routine Description:
  443. Build all NCPs for Semaphore support
  444. Arguments:
  445. Function - Supplies the subfunction from AL
  446. Connection - Supplies the server for the request
  447. Return Value:
  448. None.
  449. --*/
  450. {
  451. PUCHAR Request;
  452. NTSTATUS status;
  453. switch (Function) {
  454. UCHAR Value;
  455. UCHAR OpenCount;
  456. WORD HandleHigh, HandleLow;
  457. case 0: //OpenSemaphore
  458. Request = GetVDMPointer (
  459. (ULONG)((getDS() << 16)|getDX()),
  460. 256 * sizeof(UCHAR),
  461. IS_PROTECT_MODE());
  462. NwPrint(("Nw16: OpenSemaphore\n"));
  463. status = NwlibMakeNcp(
  464. ServerHandles[Connection],
  465. NWR_ANY_F2_NCP(0x20),
  466. Request[0] + 3, // RequestSize
  467. 5, // ResponseSize
  468. "bbr|wwb",
  469. 0,
  470. getCL(), // Semaphore Value
  471. Request, Request[0] + 1,
  472. &HandleHigh, &HandleLow,
  473. &OpenCount);
  474. if (NT_SUCCESS(status)) {
  475. setBL(OpenCount);
  476. setCX(HandleHigh);
  477. setDX(HandleLow);
  478. }
  479. break;
  480. case 1: // ExamineSemaphore
  481. NwPrint(("Nw16: ExamineSemaphore\n"));
  482. status = NwlibMakeNcp(
  483. ServerHandles[Connection],
  484. NWR_ANY_F2_NCP(0x20),
  485. 5, // RequestSize
  486. 2, // ResponseSize
  487. "bww|bb",
  488. 1,
  489. getCX(),getDX(),
  490. &Value,
  491. &OpenCount);
  492. if (NT_SUCCESS(status)) {
  493. setCX(Value);
  494. setDL(OpenCount);
  495. }
  496. break;
  497. case 2: // WaitOnSemaphore
  498. NwPrint(("Nw16: WaitOnSemaphore\n"));
  499. status = NwlibMakeNcp(
  500. ServerHandles[Connection],
  501. NWR_ANY_F2_NCP(0x20),
  502. 7, // RequestSize
  503. 0, // ResponseSize
  504. "bwww",
  505. 2,
  506. getCX(),getDX(),
  507. getBP());
  508. break;
  509. case 3: // SignalSemaphore
  510. NwPrint(("Nw16: SignalSemaphore\n"));
  511. case 4: // CloseSemaphore
  512. if (Function == 4) {
  513. NwPrint(("Nw16: CloseSemaphore\n"));
  514. }
  515. status = NwlibMakeNcp( // Close and Signal
  516. ServerHandles[Connection],
  517. NWR_ANY_F2_NCP(0x20),
  518. 5, // RequestSize
  519. 0, // ResponseSize
  520. "bww",
  521. Function,
  522. getCX(),getDX());
  523. break;
  524. default:
  525. NwPrint(("Nw16: Unknown Semaphore operation %d\n", Function));
  526. status = STATUS_INVALID_PARAMETER;
  527. break;
  528. }
  529. return status;
  530. }