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.

2998 lines
87 KiB

  1. /*
  2. * NTMSAPI.C
  3. *
  4. * RSM Service : Service API
  5. *
  6. * Author: ErvinP
  7. *
  8. * (c) 2001 Microsoft Corporation
  9. *
  10. */
  11. #include <windows.h>
  12. #include <stdlib.h>
  13. #include <wtypes.h>
  14. #include <ntmsapi.h>
  15. #include "internal.h"
  16. #include "resource.h"
  17. #include "debug.h"
  18. // BUGBUG - these need to be exposed as a COM interface w/ RPC
  19. HANDLE WINAPI OpenNtmsServerSessionW( LPCWSTR lpServer,
  20. LPCWSTR lpApplication,
  21. LPCWSTR lpClientName,
  22. LPCWSTR lpUserName,
  23. DWORD dwOptions,
  24. LPVOID lpConnectionContext)
  25. {
  26. SESSION *newSession;
  27. newSession = NewSession(lpServer, lpApplication, lpClientName, lpUserName);
  28. if (newSession){
  29. }
  30. else {
  31. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  32. }
  33. return (HANDLE)newSession;
  34. }
  35. HANDLE WINAPI OpenNtmsServerSessionA( LPCSTR lpServer,
  36. LPCSTR lpApplication,
  37. LPCSTR lpClientName,
  38. LPCSTR lpUserName,
  39. DWORD dwOptions,
  40. LPVOID lpConnectionContext)
  41. {
  42. SESSION *newSession;
  43. WCHAR wServerName[NTMS_COMPUTERNAME_LENGTH];
  44. WCHAR wAppName[NTMS_APPLICATIONNAME_LENGTH];
  45. WCHAR wClientName[NTMS_COMPUTERNAME_LENGTH];
  46. WCHAR wUserName[NTMS_USERNAME_LENGTH];
  47. AsciiToWChar(wServerName, lpServer, NTMS_COMPUTERNAME_LENGTH);
  48. AsciiToWChar(wAppName, lpApplication, NTMS_APPLICATIONNAME_LENGTH);
  49. AsciiToWChar(wClientName, lpClientName, NTMS_COMPUTERNAME_LENGTH);
  50. AsciiToWChar(wUserName, lpUserName, NTMS_USERNAME_LENGTH);
  51. newSession = OpenNtmsServerSessionW( wServerName,
  52. wAppName,
  53. wClientName,
  54. wUserName,
  55. dwOptions,
  56. lpConnectionContext);
  57. return newSession;
  58. }
  59. DWORD WINAPI CloseNtmsSession(HANDLE hSession)
  60. {
  61. HRESULT result;
  62. if (ValidateSessionHandle(hSession)){
  63. SESSION *thisSession = (SESSION *)hSession;
  64. FreeSession(thisSession);
  65. result = ERROR_SUCCESS;
  66. }
  67. else {
  68. result = ERROR_INVALID_HANDLE;
  69. }
  70. if (result != ERROR_SUCCESS){
  71. SetLastError(result);
  72. }
  73. return result;
  74. }
  75. DWORD WINAPI SubmitNtmsOperatorRequestW( HANDLE hSession,
  76. DWORD dwRequest,
  77. LPCWSTR lpMessage,
  78. LPNTMS_GUID lpArg1Id,
  79. LPNTMS_GUID lpArg2Id,
  80. LPNTMS_GUID lpRequestId)
  81. {
  82. HRESULT result = ERROR_SUCCESS;
  83. if (ValidateSessionHandle(hSession)){
  84. SESSION *thisSession = (SESSION *)hSession;
  85. switch (dwRequest){
  86. case NTMS_OPREQ_DEVICESERVICE:
  87. case NTMS_OPREQ_MOVEMEDIA:
  88. case NTMS_OPREQ_NEWMEDIA:
  89. if (!lpArg1Id){
  90. result = ERROR_INVALID_PARAMETER;
  91. }
  92. break;
  93. case NTMS_OPREQ_CLEANER:
  94. case NTMS_OPREQ_MESSAGE:
  95. break;
  96. default:
  97. DBGERR(("SubmitNtmsOperatorRequestW: unrecognized request"));
  98. result = ERROR_NOT_SUPPORTED;
  99. break;
  100. }
  101. if (result == ERROR_SUCCESS){
  102. OPERATOR_REQUEST *opReq;
  103. opReq = NewOperatorRequest(dwRequest, lpMessage, lpArg1Id, lpArg2Id);
  104. if (opReq){
  105. /*
  106. * Retrieve the localized RSM message for this op request.
  107. */
  108. switch (dwRequest){
  109. case NTMS_OPREQ_DEVICESERVICE:
  110. LoadStringW(g_hInstance, IDS_OPREQUESTDEVICESVC, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
  111. break;
  112. case NTMS_OPREQ_MOVEMEDIA:
  113. LoadStringW(g_hInstance, IDS_OPREQUESTMOVEMEDIA, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
  114. break;
  115. case NTMS_OPREQ_NEWMEDIA:
  116. LoadStringW(g_hInstance, IDS_OPREQUESTNEWMEDIA, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
  117. break;
  118. case NTMS_OPREQ_CLEANER:
  119. LoadStringW(g_hInstance, IDS_OPREQUESTCLEANER, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
  120. break;
  121. case NTMS_OPREQ_MESSAGE:
  122. LoadStringW(g_hInstance, IDS_OPREQUESTMESSAGE, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
  123. break;
  124. }
  125. *lpRequestId = opReq->opReqGuid;
  126. if (EnqueueOperatorRequest(thisSession, opReq)){
  127. result = ERROR_SUCCESS;
  128. }
  129. else {
  130. FreeOperatorRequest(opReq);
  131. result = ERROR_NOT_ENOUGH_MEMORY;
  132. }
  133. }
  134. else {
  135. result = ERROR_NOT_ENOUGH_MEMORY;
  136. }
  137. }
  138. }
  139. else {
  140. result = ERROR_INVALID_HANDLE;
  141. }
  142. if (result != ERROR_SUCCESS){
  143. SetLastError(result);
  144. }
  145. return result;
  146. }
  147. DWORD WINAPI SubmitNtmsOperatorRequestA( HANDLE hSession,
  148. DWORD dwRequest,
  149. LPCSTR lpMessage,
  150. LPNTMS_GUID lpArg1Id,
  151. LPNTMS_GUID lpArg2Id,
  152. LPNTMS_GUID lpRequestId)
  153. {
  154. WCHAR wMessage[NTMS_MESSAGE_LENGTH];
  155. HRESULT result;
  156. AsciiToWChar(wMessage, lpMessage, NTMS_MESSAGE_LENGTH);
  157. result = SubmitNtmsOperatorRequestW(hSession,
  158. dwRequest,
  159. wMessage,
  160. lpArg1Id,
  161. lpArg2Id,
  162. lpRequestId);
  163. return result;
  164. }
  165. DWORD WINAPI WaitForNtmsOperatorRequest( HANDLE hSession,
  166. LPNTMS_GUID lpRequestId,
  167. DWORD dwTimeout)
  168. {
  169. HRESULT result;
  170. if (ValidateSessionHandle(hSession)){
  171. SESSION *thisSession = (SESSION *)hSession;
  172. OPERATOR_REQUEST *opReq;
  173. EnterCriticalSection(&thisSession->lock);
  174. opReq = FindOperatorRequest(thisSession, lpRequestId);
  175. if (opReq){
  176. if ((opReq->state == NTMS_OPSTATE_COMPLETE) ||
  177. (opReq->state == NTMS_OPSTATE_REFUSED)){
  178. result = ERROR_SUCCESS;
  179. }
  180. else {
  181. opReq->numWaitingThreads++;
  182. /*
  183. * Drop the lock and wait for the op request to complete.
  184. * No race here: the opReq won't get deleted while
  185. * numWaitingThreads > 0.
  186. */
  187. LeaveCriticalSection(&thisSession->lock);
  188. WaitForSingleObject(opReq->completedEvent, dwTimeout);
  189. EnterCriticalSection(&thisSession->lock);
  190. result = (opReq->state == NTMS_OPSTATE_COMPLETE) ? ERROR_SUCCESS :
  191. (opReq->state == NTMS_OPSTATE_REFUSED) ? ERROR_CANCELLED :
  192. ERROR_TIMEOUT;
  193. ASSERT(opReq->numWaitingThreads > 0);
  194. opReq->numWaitingThreads--;
  195. }
  196. }
  197. else {
  198. result = ERROR_OBJECT_NOT_FOUND;
  199. }
  200. LeaveCriticalSection(&thisSession->lock);
  201. }
  202. else {
  203. result = ERROR_INVALID_HANDLE;
  204. }
  205. if (result != ERROR_SUCCESS){
  206. SetLastError(result);
  207. }
  208. return result;
  209. }
  210. DWORD WINAPI CancelNtmsOperatorRequest(HANDLE hSession, LPNTMS_GUID lpRequestId)
  211. {
  212. HRESULT result;
  213. if (ValidateSessionHandle(hSession)){
  214. SESSION *thisSession = (SESSION *)hSession;
  215. result = CompleteOperatorRequest(thisSession, lpRequestId, NTMS_OPSTATE_REFUSED);
  216. }
  217. else {
  218. result = ERROR_INVALID_HANDLE;
  219. }
  220. if (result != ERROR_SUCCESS){
  221. SetLastError(result);
  222. }
  223. return result;
  224. }
  225. DWORD WINAPI SatisfyNtmsOperatorRequest(HANDLE hSession, LPNTMS_GUID lpRequestId)
  226. {
  227. HRESULT result;
  228. if (ValidateSessionHandle(hSession)){
  229. SESSION *thisSession = (SESSION *)hSession;
  230. result = CompleteOperatorRequest(thisSession, lpRequestId, NTMS_OPSTATE_COMPLETE);
  231. }
  232. else {
  233. result = ERROR_INVALID_HANDLE;
  234. }
  235. if (result != ERROR_SUCCESS){
  236. SetLastError(result);
  237. }
  238. return result;
  239. }
  240. DWORD WINAPI ImportNtmsDatabase(HANDLE hSession)
  241. {
  242. HRESULT result;
  243. if (ValidateSessionHandle(hSession)){
  244. SESSION *thisSession = (SESSION *)hSession;
  245. // BUGBUG FINISH
  246. result = ERROR_SUCCESS;
  247. }
  248. else {
  249. result = ERROR_INVALID_HANDLE;
  250. }
  251. if (result != ERROR_SUCCESS){
  252. SetLastError(result);
  253. }
  254. return result;
  255. }
  256. DWORD WINAPI ExportNtmsDatabase(HANDLE hSession)
  257. {
  258. HRESULT result;
  259. if (ValidateSessionHandle(hSession)){
  260. SESSION *thisSession = (SESSION *)hSession;
  261. // BUGBUG FINISH
  262. result = ERROR_SUCCESS;
  263. }
  264. else {
  265. result = ERROR_INVALID_HANDLE;
  266. }
  267. if (result != ERROR_SUCCESS){
  268. SetLastError(result);
  269. }
  270. return result;
  271. }
  272. // BUGBUG - this API not documented and I don't understand it
  273. HRESULT WINAPI GetNtmsMountDrives( HANDLE hSession,
  274. LPNTMS_MOUNT_INFORMATION lpMountInfo,
  275. LPNTMS_GUID lpDriveId,
  276. DWORD dwCount)
  277. {
  278. HRESULT result;
  279. if (ValidateSessionHandle(hSession)){
  280. SESSION *thisSession = (SESSION *)hSession;
  281. if (lpMountInfo && lpMountInfo->lpReserved && lpDriveId && dwCount){
  282. // BUGBUG FINISH
  283. result = ERROR_SUCCESS;
  284. }
  285. else {
  286. result = ERROR_INVALID_PARAMETER;
  287. }
  288. }
  289. else {
  290. result = ERROR_INVALID_HANDLE;
  291. }
  292. if (result != ERROR_SUCCESS){
  293. SetLastError(result);
  294. }
  295. return result;
  296. }
  297. DWORD WINAPI AllocateNtmsMedia( HANDLE hSession,
  298. LPNTMS_GUID lpMediaPoolId,
  299. LPNTMS_GUID lpPartitionId, // optional
  300. LPNTMS_GUID lpMediaId, // in/out
  301. DWORD dwOptions,
  302. DWORD dwTimeout,
  303. LPNTMS_ALLOCATION_INFORMATION lpAllocateInfo)
  304. {
  305. HRESULT result;
  306. if (ValidateSessionHandle(hSession)){
  307. SESSION *thisSession = (SESSION *)hSession;
  308. MEDIA_POOL *mediaPool;
  309. mediaPool = FindMediaPool(lpMediaPoolId);
  310. if (mediaPool){
  311. PHYSICAL_MEDIA *physMedia;
  312. if (dwOptions & NTMS_ALLOCATE_NEW){
  313. /*
  314. * Allocate the first partition (side) of the specified media
  315. * with a reservation on all other partitions.
  316. */
  317. if (lpPartitionId){
  318. physMedia = FindPhysicalMedia(lpMediaId);
  319. if (physMedia){
  320. result = AllocatePhysicalMediaExclusive(thisSession, physMedia, lpPartitionId, dwTimeout);
  321. DerefObject(physMedia);
  322. }
  323. else {
  324. result = ERROR_INVALID_PARAMETER;
  325. }
  326. }
  327. else {
  328. ASSERT(lpPartitionId);
  329. result = ERROR_INVALID_PARAMETER;
  330. }
  331. }
  332. else if (dwOptions & NTMS_ALLOCATE_NEXT){
  333. /*
  334. * The specified media is (ostensibly) owned by the caller.
  335. * Allocate the next available partition for him.
  336. */
  337. physMedia = FindPhysicalMedia(lpMediaId);
  338. if (physMedia){
  339. MEDIA_PARTITION *nextMediaPartition;
  340. ASSERT(!lpPartitionId);
  341. result = AllocateNextPartitionOnExclusiveMedia(thisSession, physMedia, &nextMediaPartition);
  342. if (result == ERROR_SUCCESS){
  343. *lpMediaId = nextMediaPartition->logicalMediaGuid;
  344. }
  345. DerefObject(physMedia);
  346. }
  347. else {
  348. result = ERROR_INVALID_PARAMETER;
  349. }
  350. }
  351. else {
  352. // BUGBUG - are we reserving a physMedia or just
  353. // a partition here ?
  354. BOOL opReqIfNeeded = (dwOptions & NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE) ? FALSE : TRUE;
  355. result = AllocateMediaFromPool(thisSession, mediaPool, dwTimeout, &physMedia, opReqIfNeeded);
  356. if (result == ERROR_SUCCESS){
  357. // BUGBUG - return logicalMediaId ??
  358. *lpMediaId = physMedia->objHeader.guid;
  359. }
  360. }
  361. DerefObject(mediaPool);
  362. }
  363. else {
  364. result = ERROR_INVALID_MEDIA_POOL;
  365. }
  366. }
  367. else {
  368. result = ERROR_INVALID_HANDLE;
  369. }
  370. if (result != ERROR_SUCCESS){
  371. SetLastError(result);
  372. }
  373. return result;
  374. }
  375. DWORD WINAPI DeallocateNtmsMedia( HANDLE hSession,
  376. LPNTMS_GUID lpLogicalMediaId,
  377. DWORD dwOptions)
  378. {
  379. HRESULT result;
  380. if (ValidateSessionHandle(hSession)){
  381. SESSION *thisSession = (SESSION *)hSession;
  382. MEDIA_PARTITION *thisMediaPartition;
  383. thisMediaPartition = FindMediaPartition(lpLogicalMediaId);
  384. if (thisMediaPartition){
  385. result = ReleaseMediaPartition(thisSession, thisMediaPartition);
  386. }
  387. else {
  388. result = ERROR_INVALID_MEDIA;
  389. }
  390. }
  391. else {
  392. result = ERROR_INVALID_HANDLE;
  393. }
  394. if (result != ERROR_SUCCESS){
  395. SetLastError(result);
  396. }
  397. return result;
  398. }
  399. DWORD WINAPI SwapNtmsMedia( HANDLE hSession,
  400. LPNTMS_GUID lpMediaId1,
  401. LPNTMS_GUID lpMediaId2)
  402. {
  403. HRESULT result;
  404. if (ValidateSessionHandle(hSession)){
  405. SESSION *thisSession = (SESSION *)hSession;
  406. // BUGBUG FINISH
  407. result = ERROR_SUCCESS;
  408. }
  409. else {
  410. result = ERROR_INVALID_HANDLE;
  411. }
  412. if (result != ERROR_SUCCESS){
  413. SetLastError(result);
  414. }
  415. return result;
  416. }
  417. DWORD WINAPI DecommissionNtmsMedia( HANDLE hSession,
  418. LPNTMS_GUID lpMediaPartId)
  419. {
  420. HRESULT result;
  421. if (ValidateSessionHandle(hSession)){
  422. SESSION *thisSession = (SESSION *)hSession;
  423. MEDIA_PARTITION *mediaPart;
  424. mediaPart = FindMediaPartition(lpMediaPartId);
  425. if (mediaPart){
  426. result = SetMediaPartitionState( mediaPart,
  427. MEDIAPARTITIONSTATE_DECOMMISSIONED);
  428. DerefObject(mediaPart);
  429. }
  430. else {
  431. result = ERROR_INVALID_HANDLE;
  432. }
  433. }
  434. else {
  435. result = ERROR_INVALID_HANDLE;
  436. }
  437. if (result != ERROR_SUCCESS){
  438. SetLastError(result);
  439. }
  440. return result;
  441. }
  442. DWORD WINAPI SetNtmsMediaComplete( HANDLE hSession,
  443. LPNTMS_GUID lpMediaPartId)
  444. {
  445. HRESULT result;
  446. if (ValidateSessionHandle(hSession)){
  447. SESSION *thisSession = (SESSION *)hSession;
  448. MEDIA_PARTITION *mediaPart;
  449. mediaPart = FindMediaPartition(lpMediaPartId);
  450. if (mediaPart){
  451. result = SetMediaPartitionComplete(mediaPart);
  452. DerefObject(mediaPart);
  453. }
  454. else {
  455. result = ERROR_INVALID_HANDLE;
  456. }
  457. result = ERROR_SUCCESS;
  458. }
  459. else {
  460. result = ERROR_INVALID_HANDLE;
  461. }
  462. if (result != ERROR_SUCCESS){
  463. SetLastError(result);
  464. }
  465. return result;
  466. }
  467. DWORD WINAPI DeleteNtmsMedia( HANDLE hSession,
  468. LPNTMS_GUID lpPhysMediaId)
  469. {
  470. HRESULT result;
  471. if (ValidateSessionHandle(hSession)){
  472. SESSION *thisSession = (SESSION *)hSession;
  473. PHYSICAL_MEDIA *physMedia;
  474. physMedia = FindPhysicalMedia(lpPhysMediaId);
  475. if (physMedia){
  476. result = DeletePhysicalMedia(physMedia);
  477. DerefObject(physMedia);
  478. }
  479. else {
  480. result = ERROR_INVALID_HANDLE;
  481. }
  482. }
  483. else {
  484. result = ERROR_INVALID_HANDLE;
  485. }
  486. if (result != ERROR_SUCCESS){
  487. SetLastError(result);
  488. }
  489. return result;
  490. }
  491. DWORD WINAPI CreateNtmsMediaPoolW( HANDLE hSession,
  492. LPCWSTR lpPoolName,
  493. LPNTMS_GUID lpMediaType,
  494. DWORD dwAction,
  495. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  496. OUT LPNTMS_GUID lpPoolId)
  497. {
  498. HRESULT result;
  499. if (ValidateSessionHandle(hSession)){
  500. SESSION *thisSession = (SESSION *)hSession;
  501. MEDIA_POOL *mediaPool;
  502. mediaPool = FindMediaPoolByName((PWSTR)lpPoolName);
  503. if (dwAction == NTMS_OPEN_EXISTING){
  504. if (mediaPool){
  505. *lpPoolId = mediaPool->objHeader.guid;
  506. result = ERROR_SUCCESS;
  507. }
  508. else {
  509. result = ERROR_OBJECT_NOT_FOUND;
  510. }
  511. }
  512. else if (dwAction == NTMS_OPEN_ALWAYS){
  513. if (mediaPool){
  514. *lpPoolId = mediaPool->objHeader.guid;
  515. result = ERROR_SUCCESS;
  516. }
  517. else {
  518. mediaPool = NewMediaPool(lpPoolName, lpMediaType, lpSecurityAttributes);
  519. if (mediaPool){
  520. // BUGBUG FINISH
  521. *lpPoolId = mediaPool->objHeader.guid;
  522. result = ERROR_SUCCESS;
  523. }
  524. else {
  525. result = ERROR_DATABASE_FAILURE;
  526. }
  527. }
  528. }
  529. else if (dwAction == NTMS_CREATE_NEW){
  530. /*
  531. * Caller is trying to open a new media pool.
  532. * So if one by that name already exists, fail.
  533. */
  534. if (mediaPool){
  535. DerefObject(mediaPool);
  536. result = ERROR_ALREADY_EXISTS;
  537. }
  538. else {
  539. mediaPool = NewMediaPool(lpPoolName, lpMediaType, lpSecurityAttributes);
  540. if (mediaPool){
  541. // BUGBUG FINISH
  542. *lpPoolId = mediaPool->objHeader.guid;
  543. result = ERROR_SUCCESS;
  544. }
  545. else {
  546. result = ERROR_DATABASE_FAILURE;
  547. }
  548. }
  549. }
  550. else {
  551. result = ERROR_INVALID_PARAMETER;
  552. }
  553. }
  554. else {
  555. result = ERROR_INVALID_HANDLE;
  556. }
  557. if (result != ERROR_SUCCESS){
  558. SetLastError(result);
  559. }
  560. return result;
  561. }
  562. DWORD WINAPI CreateNtmsMediaPoolA( HANDLE hSession,
  563. LPCSTR lpPoolName,
  564. LPNTMS_GUID lpMediaType,
  565. DWORD dwAction,
  566. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  567. OUT LPNTMS_GUID lpPoolId)
  568. {
  569. HRESULT result;
  570. WCHAR wPoolName[NTMS_OBJECTNAME_LENGTH];
  571. AsciiToWChar(wPoolName, lpPoolName, NTMS_OBJECTNAME_LENGTH);
  572. result = CreateNtmsMediaPoolW( hSession,
  573. wPoolName,
  574. lpMediaType,
  575. dwAction,
  576. lpSecurityAttributes,
  577. lpPoolId);
  578. return result;
  579. }
  580. DWORD WINAPI GetNtmsMediaPoolNameW( HANDLE hSession,
  581. LPNTMS_GUID lpPoolId,
  582. LPWSTR lpBufName,
  583. LPDWORD lpdwNameSize)
  584. {
  585. HRESULT result;
  586. if (ValidateSessionHandle(hSession)){
  587. SESSION *thisSession = (SESSION *)hSession;
  588. MEDIA_POOL *mediaPool;
  589. mediaPool = FindMediaPool(lpPoolId);
  590. if (mediaPool){
  591. ULONG numChars;
  592. EnterCriticalSection(&mediaPool->lock);
  593. numChars = wcslen(mediaPool->name)+1;
  594. ASSERT(numChars < NTMS_OBJECTNAME_LENGTH);
  595. if (*lpdwNameSize >= numChars){
  596. numChars = WStrNCpy(lpBufName, mediaPool->name, *lpdwNameSize);
  597. result = ERROR_SUCCESS;
  598. }
  599. else {
  600. result = ERROR_INSUFFICIENT_BUFFER;
  601. }
  602. *lpdwNameSize = numChars;
  603. LeaveCriticalSection(&mediaPool->lock);
  604. DerefObject(mediaPool);
  605. }
  606. else {
  607. result = ERROR_INVALID_HANDLE;
  608. }
  609. }
  610. else {
  611. result = ERROR_INVALID_HANDLE;
  612. }
  613. if (result != ERROR_SUCCESS){
  614. SetLastError(result);
  615. }
  616. return result;
  617. }
  618. DWORD WINAPI GetNtmsMediaPoolNameA( HANDLE hSession,
  619. LPNTMS_GUID lpPoolId,
  620. LPSTR lpBufName,
  621. LPDWORD lpdwNameSize)
  622. {
  623. HRESULT result;
  624. if (*lpdwNameSize > NTMS_OBJECTNAME_LENGTH){
  625. ASSERT(*lpdwNameSize <= NTMS_OBJECTNAME_LENGTH);
  626. result = ERROR_INVALID_PARAMETER;
  627. }
  628. else {
  629. WCHAR wBufName[NTMS_OBJECTNAME_LENGTH];
  630. result = GetNtmsMediaPoolNameW(hSession, lpPoolId, wBufName, lpdwNameSize);
  631. if (result == ERROR_SUCCESS){
  632. WCharToAscii(lpBufName, wBufName, *lpdwNameSize);
  633. }
  634. }
  635. return result;
  636. }
  637. DWORD WINAPI MoveToNtmsMediaPool( HANDLE hSession,
  638. LPNTMS_GUID lpPhysMediaId,
  639. LPNTMS_GUID lpPoolId)
  640. {
  641. HRESULT result;
  642. if (ValidateSessionHandle(hSession)){
  643. SESSION *thisSession = (SESSION *)hSession;
  644. PHYSICAL_MEDIA *physMedia;
  645. physMedia = FindPhysicalMedia(lpPhysMediaId);
  646. if (physMedia){
  647. MEDIA_POOL *destMediaPool;
  648. destMediaPool = FindMediaPool(lpPoolId);
  649. if (destMediaPool){
  650. result = MovePhysicalMediaToPool(destMediaPool, physMedia, FALSE);
  651. DerefObject(destMediaPool);
  652. }
  653. else {
  654. result = ERROR_INVALID_HANDLE;
  655. }
  656. DerefObject(physMedia);
  657. }
  658. else {
  659. result = ERROR_INVALID_HANDLE;
  660. }
  661. }
  662. else {
  663. result = ERROR_INVALID_HANDLE;
  664. }
  665. if (result != ERROR_SUCCESS){
  666. SetLastError(result);
  667. }
  668. return result;
  669. }
  670. DWORD WINAPI DeleteNtmsMediaPool(HANDLE hSession, LPNTMS_GUID lpPoolId)
  671. {
  672. HRESULT result;
  673. if (ValidateSessionHandle(hSession)){
  674. SESSION *thisSession = (SESSION *)hSession;
  675. MEDIA_POOL *mediaPool;
  676. mediaPool = FindMediaPool(lpPoolId);
  677. if (mediaPool){
  678. result = DeleteMediaPool(mediaPool);
  679. DerefObject(mediaPool);
  680. }
  681. else {
  682. result = ERROR_INVALID_MEDIA_POOL;
  683. }
  684. }
  685. else {
  686. result = ERROR_INVALID_HANDLE;
  687. }
  688. if (result != ERROR_SUCCESS){
  689. SetLastError(result);
  690. }
  691. return result;
  692. }
  693. DWORD WINAPI AddNtmsMediaType( HANDLE hSession,
  694. LPNTMS_GUID lpMediaTypeId,
  695. LPNTMS_GUID lpLibId)
  696. {
  697. HRESULT result;
  698. if (ValidateSessionHandle(hSession)){
  699. SESSION *thisSession = (SESSION *)hSession;
  700. LIBRARY *lib;
  701. lib = FindLibrary(lpLibId);
  702. if (lib){
  703. MEDIA_TYPE_OBJECT *mediaTypeObj;
  704. mediaTypeObj = FindMediaTypeObject(lpMediaTypeId);
  705. if (mediaTypeObj){
  706. /*
  707. * The media type is already defined. Succeed.
  708. */
  709. DerefObject(mediaTypeObj);
  710. result = ERROR_SUCCESS;
  711. }
  712. else {
  713. mediaTypeObj = NewMediaTypeObject(lib);
  714. if (mediaTypeObj){
  715. // BUGBUG FINISH - create new standard media pools
  716. result = ERROR_SUCCESS;
  717. }
  718. else {
  719. result = ERROR_NOT_ENOUGH_MEMORY;
  720. }
  721. }
  722. DerefObject(lib);
  723. }
  724. else {
  725. result = ERROR_INVALID_LIBRARY;
  726. }
  727. }
  728. else {
  729. result = ERROR_INVALID_HANDLE;
  730. }
  731. if (result != ERROR_SUCCESS){
  732. SetLastError(result);
  733. }
  734. return result;
  735. }
  736. DWORD WINAPI DeleteNtmsMediaType( HANDLE hSession,
  737. LPNTMS_GUID lpMediaTypeId,
  738. LPNTMS_GUID lpLibId)
  739. {
  740. HRESULT result;
  741. if (ValidateSessionHandle(hSession)){
  742. SESSION *thisSession = (SESSION *)hSession;
  743. LIBRARY *lib;
  744. lib = FindLibrary(lpLibId);
  745. if (lib){
  746. MEDIA_TYPE_OBJECT *mediaTypeObj;
  747. mediaTypeObj = FindMediaTypeObject(lpMediaTypeId);
  748. if (mediaTypeObj){
  749. result = DeleteMediaTypeObject(mediaTypeObj);
  750. DerefObject(mediaTypeObj);
  751. }
  752. else {
  753. result = ERROR_INVALID_PARAMETER;
  754. }
  755. DerefObject(lib);
  756. }
  757. else {
  758. result = ERROR_INVALID_LIBRARY;
  759. }
  760. }
  761. else {
  762. result = ERROR_INVALID_HANDLE;
  763. }
  764. if (result != ERROR_SUCCESS){
  765. SetLastError(result);
  766. }
  767. return result;
  768. }
  769. /*
  770. * ChangeNtmsMediaType
  771. *
  772. * Move the media to the media pool and change the media's
  773. * type to the pool's media type.
  774. */
  775. DWORD WINAPI ChangeNtmsMediaType( HANDLE hSession,
  776. LPNTMS_GUID lpMediaId,
  777. LPNTMS_GUID lpPoolId)
  778. {
  779. HRESULT result;
  780. if (ValidateSessionHandle(hSession)){
  781. SESSION *thisSession = (SESSION *)hSession;
  782. PHYSICAL_MEDIA *physMedia;
  783. physMedia = FindPhysicalMedia(lpMediaId);
  784. if (physMedia){
  785. MEDIA_POOL *destMediaPool;
  786. destMediaPool = FindMediaPool(lpPoolId);
  787. if (destMediaPool){
  788. result = MovePhysicalMediaToPool(destMediaPool, physMedia, TRUE);
  789. DerefObject(destMediaPool);
  790. }
  791. else {
  792. result = ERROR_INVALID_HANDLE;
  793. }
  794. DerefObject(physMedia);
  795. }
  796. else {
  797. result = ERROR_INVALID_HANDLE;
  798. }
  799. }
  800. else {
  801. result = ERROR_INVALID_HANDLE;
  802. }
  803. if (result != ERROR_SUCCESS){
  804. SetLastError(result);
  805. }
  806. return result;
  807. }
  808. DWORD WINAPI MountNtmsMedia(HANDLE hSession,
  809. LPNTMS_GUID lpMediaOrPartitionIds,
  810. IN OUT LPNTMS_GUID lpDriveIds,
  811. DWORD dwCount,
  812. DWORD dwOptions,
  813. int dwPriority,
  814. DWORD dwTimeout,
  815. LPNTMS_MOUNT_INFORMATION lpMountInfo)
  816. {
  817. HRESULT result;
  818. if (ValidateSessionHandle(hSession)){
  819. SESSION *thisSession = (SESSION *)hSession;
  820. /*
  821. * Validate that we can safely read the media and drive GUIDs
  822. * that were passed in by the caller (this just verifies that the
  823. * buffers are readable; it doesn't verify the GUIDs themselves).
  824. */
  825. if (ValidateBuffer(lpMediaOrPartitionIds, dwCount*sizeof(NTMS_GUID))){
  826. if (ValidateBuffer(lpDriveIds, dwCount*sizeof(NTMS_GUID))){
  827. WORKGROUP *workGroup;
  828. /*
  829. * Create a work group, which is a group of workItems,
  830. * to service each component of the mount.
  831. */
  832. workGroup = NewWorkGroup();
  833. if (workGroup){
  834. result = BuildMountWorkGroup( workGroup,
  835. lpMediaOrPartitionIds,
  836. lpDriveIds,
  837. dwCount,
  838. dwOptions,
  839. dwPriority);
  840. if (result == ERROR_SUCCESS){
  841. /*
  842. * Give the mount workItems to the library thread.
  843. */
  844. result = ScheduleWorkGroup(workGroup);
  845. if (result == ERROR_SUCCESS){
  846. DWORD waitRes;
  847. /*
  848. * Wait for all the mounts to complete.
  849. */
  850. waitRes = WaitForSingleObject(workGroup->allWorkItemsCompleteEvent, dwTimeout);
  851. if (waitRes == WAIT_TIMEOUT){
  852. result = ERROR_TIMEOUT;
  853. }
  854. else {
  855. result = workGroup->resultStatus;
  856. }
  857. }
  858. FreeWorkGroup(workGroup);
  859. }
  860. }
  861. else {
  862. result = ERROR_NOT_ENOUGH_MEMORY;
  863. }
  864. }
  865. else {
  866. result = ERROR_INVALID_DRIVE;
  867. }
  868. }
  869. else {
  870. result = ERROR_INVALID_MEDIA;
  871. }
  872. }
  873. else {
  874. result = ERROR_INVALID_HANDLE;
  875. }
  876. if (result != ERROR_SUCCESS){
  877. SetLastError(result);
  878. }
  879. return result;
  880. }
  881. DWORD WINAPI DismountNtmsMedia( HANDLE hSession,
  882. LPNTMS_GUID lpMediaOrPartitionIds,
  883. DWORD dwCount,
  884. DWORD dwOptions)
  885. {
  886. HRESULT result;
  887. if (ValidateSessionHandle(hSession)){
  888. SESSION *thisSession = (SESSION *)hSession;
  889. if (ValidateBuffer(lpMediaOrPartitionIds, dwCount*sizeof(NTMS_GUID))){
  890. WORKGROUP *workGroup;
  891. /*
  892. * Create a work group, which is a group of workItems,
  893. * to service each component of the mount.
  894. */
  895. workGroup = NewWorkGroup();
  896. if (workGroup){
  897. result = BuildDismountWorkGroup( workGroup,
  898. lpMediaOrPartitionIds,
  899. dwCount,
  900. dwOptions);
  901. if (result == ERROR_SUCCESS){
  902. /*
  903. * Give the mount workItems to the library thread.
  904. */
  905. result = ScheduleWorkGroup(workGroup);
  906. if (result == ERROR_SUCCESS){
  907. /*
  908. * Wait for all the mounts to complete.
  909. */
  910. WaitForSingleObject(workGroup->allWorkItemsCompleteEvent, INFINITE);
  911. result = workGroup->resultStatus;
  912. }
  913. FreeWorkGroup(workGroup);
  914. }
  915. }
  916. else {
  917. result = ERROR_NOT_ENOUGH_MEMORY;
  918. }
  919. }
  920. else {
  921. result = ERROR_INVALID_MEDIA;
  922. }
  923. }
  924. else {
  925. result = ERROR_INVALID_HANDLE;
  926. }
  927. if (result != ERROR_SUCCESS){
  928. SetLastError(result);
  929. }
  930. return result;
  931. }
  932. DWORD WINAPI EjectNtmsMedia(HANDLE hSession,
  933. LPNTMS_GUID lpMediaId,
  934. LPNTMS_GUID lpEjectOperation,
  935. DWORD dwAction)
  936. {
  937. HRESULT result;
  938. if (ValidateSessionHandle(hSession)){
  939. SESSION *thisSession = (SESSION *)hSession;
  940. PHYSICAL_MEDIA *physMedia;
  941. physMedia = FindPhysicalMedia(lpMediaId);
  942. if (physMedia){
  943. MEDIA_POOL *mediaPool;
  944. LIBRARY *lib;
  945. /*
  946. * Get the library for this media.
  947. */
  948. LockPhysicalMediaWithLibrary(physMedia);
  949. mediaPool = physMedia->owningMediaPool;
  950. lib = mediaPool ? mediaPool->owningLibrary : NULL;
  951. if (lib){
  952. RefObject(lib);
  953. }
  954. UnlockPhysicalMediaWithLibrary(physMedia);
  955. if (lib){
  956. WORKITEM *workItem;
  957. workItem = DequeueFreeWorkItem(lib, TRUE);
  958. if (workItem){
  959. /*
  960. * Build the workItem for the eject.
  961. */
  962. BuildEjectWorkItem(workItem, physMedia, lpEjectOperation, dwAction);
  963. /*
  964. * Give this workItem to the library and wake up the library thread.
  965. * Then wait for the workItem to complete.
  966. */
  967. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  968. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  969. /*
  970. * Get result from the completed workItem.
  971. * Also get result parameters (eject guid is returned
  972. * when dwAction = NTMS_EJECT_START).
  973. */
  974. result = workItem->currentOp.resultStatus;
  975. *lpEjectOperation = workItem->currentOp.guidArg;
  976. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  977. }
  978. else {
  979. result = ERROR_NOT_ENOUGH_MEMORY;
  980. }
  981. DerefObject(lib);
  982. }
  983. else {
  984. result = ERROR_DATABASE_FAILURE;
  985. }
  986. DerefObject(physMedia);
  987. }
  988. else {
  989. result = ERROR_INVALID_MEDIA;
  990. }
  991. }
  992. else {
  993. result = ERROR_INVALID_HANDLE;
  994. }
  995. if (result != ERROR_SUCCESS){
  996. SetLastError(result);
  997. }
  998. return result;
  999. }
  1000. DWORD WINAPI InjectNtmsMedia( HANDLE hSession,
  1001. LPNTMS_GUID lpLibraryId,
  1002. LPNTMS_GUID lpInjectOperation,
  1003. DWORD dwAction)
  1004. {
  1005. HRESULT result;
  1006. if (ValidateSessionHandle(hSession)){
  1007. SESSION *thisSession = (SESSION *)hSession;
  1008. LIBRARY *lib;
  1009. lib = FindLibrary(lpLibraryId);
  1010. if (lib){
  1011. if (lib->state == LIBSTATE_ONLINE){
  1012. WORKITEM *workItem;
  1013. workItem = DequeueFreeWorkItem(lib, TRUE);
  1014. if (workItem){
  1015. /*
  1016. * Build the workItem for the inject.
  1017. */
  1018. BuildInjectWorkItem(workItem, lpInjectOperation, dwAction);
  1019. /*
  1020. * Give this workItem to the library and wake up the library thread.
  1021. * Then wait for the workItem to complete.
  1022. */
  1023. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1024. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1025. /*
  1026. * Get result from the completed workItem.
  1027. */
  1028. result = workItem->currentOp.resultStatus;
  1029. *lpInjectOperation = workItem->currentOp.guidArg;
  1030. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1031. }
  1032. else {
  1033. result = ERROR_NOT_ENOUGH_MEMORY;
  1034. }
  1035. }
  1036. else {
  1037. result = ERROR_LIBRARY_OFFLINE;
  1038. }
  1039. DerefObject(lib);
  1040. }
  1041. else {
  1042. result = ERROR_INVALID_HANDLE;
  1043. }
  1044. }
  1045. else {
  1046. result = ERROR_INVALID_HANDLE;
  1047. }
  1048. if (result != ERROR_SUCCESS){
  1049. SetLastError(result);
  1050. }
  1051. return result;
  1052. }
  1053. DWORD WINAPI AccessNtmsLibraryDoor( HANDLE hSession,
  1054. LPNTMS_GUID lpLibraryId,
  1055. DWORD dwAction)
  1056. {
  1057. HRESULT result;
  1058. if (ValidateSessionHandle(hSession)){
  1059. SESSION *thisSession = (SESSION *)hSession;
  1060. LIBRARY *lib;
  1061. lib = FindLibrary(lpLibraryId);
  1062. if (lib){
  1063. if (lib->state == LIBSTATE_ONLINE){
  1064. WORKITEM *workItem;
  1065. workItem = DequeueFreeWorkItem(lib, TRUE);
  1066. if (workItem){
  1067. /*
  1068. * Build the workItem for the door unlock.
  1069. */
  1070. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1071. workItem->currentOp.opcode = NTMS_LM_DOORACCESS;
  1072. workItem->currentOp.options = dwAction;
  1073. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1074. /*
  1075. * Give this workItem to the library and wake up the library thread.
  1076. */
  1077. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1078. /*
  1079. * Wait for the request to be processed by the library thread.
  1080. * Note: If the library is busy, the workItem will be completed
  1081. * immediately and the door will be unlocked later.
  1082. */
  1083. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1084. /*
  1085. * Get result from the completed workItem.
  1086. */
  1087. result = workItem->currentOp.resultStatus;
  1088. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1089. }
  1090. else {
  1091. result = ERROR_NOT_ENOUGH_MEMORY;
  1092. }
  1093. }
  1094. else {
  1095. result = ERROR_LIBRARY_OFFLINE;
  1096. }
  1097. DerefObject(lib);
  1098. }
  1099. else {
  1100. result = ERROR_INVALID_HANDLE;
  1101. }
  1102. }
  1103. else {
  1104. result = ERROR_INVALID_HANDLE;
  1105. }
  1106. if (result != ERROR_SUCCESS){
  1107. SetLastError(result);
  1108. }
  1109. return result;
  1110. }
  1111. DWORD WINAPI CleanNtmsDrive(HANDLE hSession, LPNTMS_GUID lpDriveId)
  1112. {
  1113. HRESULT result;
  1114. if (ValidateSessionHandle(hSession)){
  1115. SESSION *thisSession = (SESSION *)hSession;
  1116. DRIVE *drive;
  1117. drive = FindDrive(lpDriveId);
  1118. if (drive){
  1119. WORKITEM *workItem;
  1120. ASSERT(drive->lib);
  1121. workItem = DequeueFreeWorkItem(drive->lib, TRUE);
  1122. if (workItem){
  1123. /*
  1124. * Build the workItem to clean the drive.
  1125. * Reference every object pointed to by the workItem.
  1126. */
  1127. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1128. workItem->currentOp.opcode = NTMS_LM_CLEANDRIVE;
  1129. workItem->currentOp.drive = drive;
  1130. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1131. RefObject(drive);
  1132. /*
  1133. * Give this workItem to the library and wake up the library thread.
  1134. */
  1135. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1136. /*
  1137. * Wait for the request to be processed by the library thread.
  1138. */
  1139. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1140. /*
  1141. * Get result from the completed workItem.
  1142. */
  1143. result = workItem->currentOp.resultStatus;
  1144. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1145. }
  1146. else {
  1147. result = ERROR_NOT_ENOUGH_MEMORY;
  1148. }
  1149. DerefObject(drive);
  1150. }
  1151. else {
  1152. result = ERROR_INVALID_DRIVE;
  1153. }
  1154. }
  1155. else {
  1156. result = ERROR_INVALID_HANDLE;
  1157. }
  1158. if (result != ERROR_SUCCESS){
  1159. SetLastError(result);
  1160. }
  1161. return result;
  1162. }
  1163. DWORD WINAPI DismountNtmsDrive(HANDLE hSession, LPNTMS_GUID lpDriveId)
  1164. {
  1165. HRESULT result;
  1166. if (ValidateSessionHandle(hSession)){
  1167. SESSION *thisSession = (SESSION *)hSession;
  1168. DRIVE *drive;
  1169. drive = FindDrive(lpDriveId);
  1170. if (drive){
  1171. WORKITEM *workItem;
  1172. workItem = DequeueFreeWorkItem(drive->lib, TRUE);
  1173. if (workItem){
  1174. /*
  1175. * Build the workItem to dismount.
  1176. * Reference every object pointed to by the workItem.
  1177. */
  1178. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1179. workItem->currentOp.opcode = NTMS_LM_DISMOUNT;
  1180. workItem->currentOp.drive = drive;
  1181. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1182. RefObject(drive);
  1183. /*
  1184. * Give this workItem to the library and wake up the library thread.
  1185. */
  1186. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1187. /*
  1188. * Wait for the request to be processed by the library thread.
  1189. */
  1190. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1191. /*
  1192. * Get result from the completed workItem.
  1193. */
  1194. result = workItem->currentOp.resultStatus;
  1195. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1196. }
  1197. else {
  1198. result = ERROR_NOT_ENOUGH_MEMORY;
  1199. }
  1200. DerefObject(drive);
  1201. }
  1202. else {
  1203. result = ERROR_INVALID_DRIVE;
  1204. }
  1205. }
  1206. else {
  1207. result = ERROR_INVALID_HANDLE;
  1208. }
  1209. if (result != ERROR_SUCCESS){
  1210. SetLastError(result);
  1211. }
  1212. return result;
  1213. }
  1214. DWORD WINAPI InventoryNtmsLibrary( HANDLE hSession,
  1215. LPNTMS_GUID lpLibraryId,
  1216. DWORD dwAction)
  1217. {
  1218. HRESULT result;
  1219. if (ValidateSessionHandle(hSession)){
  1220. SESSION *thisSession = (SESSION *)hSession;
  1221. LIBRARY *lib;
  1222. lib = FindLibrary(lpLibraryId);
  1223. if (lib){
  1224. if (lib->state == LIBSTATE_ONLINE){
  1225. WORKITEM *workItem;
  1226. workItem = DequeueFreeWorkItem(lib, TRUE);
  1227. if (workItem){
  1228. /*
  1229. * Build the workItem for the inventory.
  1230. */
  1231. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1232. workItem->currentOp.opcode = NTMS_LM_INVENTORY;
  1233. workItem->currentOp.options = dwAction;
  1234. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1235. /*
  1236. * Give this workItem to the library and wake up the library thread.
  1237. */
  1238. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1239. /*
  1240. * Wait for the request to be processed by the library thread.
  1241. * Note: If the library is busy, the workItem will be completed
  1242. * immediately and the inventory will happen later.
  1243. */
  1244. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1245. /*
  1246. * Get result from the completed workItem.
  1247. */
  1248. result = workItem->currentOp.resultStatus;
  1249. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1250. }
  1251. else {
  1252. result = ERROR_NOT_ENOUGH_MEMORY;
  1253. }
  1254. }
  1255. else {
  1256. result = ERROR_LIBRARY_OFFLINE;
  1257. }
  1258. DerefObject(lib);
  1259. }
  1260. else {
  1261. result = ERROR_INVALID_HANDLE;
  1262. }
  1263. }
  1264. else {
  1265. result = ERROR_INVALID_HANDLE;
  1266. }
  1267. if (result != ERROR_SUCCESS){
  1268. SetLastError(result);
  1269. }
  1270. return result;
  1271. }
  1272. DWORD WINAPI UpdateNtmsOmidInfo( HANDLE hSession,
  1273. LPNTMS_GUID lpLogicalMediaId,
  1274. DWORD labelType,
  1275. DWORD numberOfBytes,
  1276. LPVOID lpBuffer)
  1277. {
  1278. HRESULT result;
  1279. if (ValidateSessionHandle(hSession)){
  1280. SESSION *thisSession = (SESSION *)hSession;
  1281. MEDIA_PARTITION *mediaPart;
  1282. mediaPart = FindMediaPartition(lpLogicalMediaId);
  1283. if (mediaPart){
  1284. MEDIA_POOL *mediaPool;
  1285. LIBRARY *lib;
  1286. ASSERT(mediaPart->owningPhysicalMedia);
  1287. /*
  1288. * Get the library for this media.
  1289. */
  1290. LockPhysicalMediaWithLibrary(mediaPart->owningPhysicalMedia);
  1291. mediaPool = mediaPart->owningPhysicalMedia->owningMediaPool;
  1292. lib = mediaPool ? mediaPool->owningLibrary : NULL;
  1293. if (lib){
  1294. RefObject(lib);
  1295. }
  1296. UnlockPhysicalMediaWithLibrary(mediaPart->owningPhysicalMedia);
  1297. if (lib){
  1298. WORKITEM *workItem;
  1299. workItem = DequeueFreeWorkItem(lib, TRUE);
  1300. if (workItem){
  1301. /*
  1302. * Build the workItem.
  1303. */
  1304. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1305. workItem->currentOp.opcode = NTMS_LM_UPDATEOMID;
  1306. workItem->currentOp.options = labelType;
  1307. workItem->currentOp.buf = lpBuffer;
  1308. workItem->currentOp.bufLen = numberOfBytes;
  1309. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1310. /*
  1311. * Give this workItem to the library and wake up the library thread.
  1312. */
  1313. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1314. /*
  1315. * Wait for the request to be processed by the library thread.
  1316. */
  1317. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1318. /*
  1319. * Get result from the completed workItem.
  1320. */
  1321. result = workItem->currentOp.resultStatus;
  1322. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1323. }
  1324. else {
  1325. result = ERROR_NOT_ENOUGH_MEMORY;
  1326. }
  1327. DerefObject(lib);
  1328. }
  1329. else {
  1330. result = ERROR_DATABASE_FAILURE;
  1331. }
  1332. DerefObject(mediaPart);
  1333. }
  1334. else {
  1335. result = ERROR_INVALID_MEDIA;
  1336. }
  1337. }
  1338. else {
  1339. result = ERROR_INVALID_HANDLE;
  1340. }
  1341. if (result != ERROR_SUCCESS){
  1342. SetLastError(result);
  1343. }
  1344. return result;
  1345. }
  1346. DWORD WINAPI CancelNtmsLibraryRequest(HANDLE hSession, LPNTMS_GUID lpRequestId)
  1347. {
  1348. HRESULT result;
  1349. if (ValidateSessionHandle(hSession)){
  1350. SESSION *thisSession = (SESSION *)hSession;
  1351. WORKITEM *workItem = NULL;
  1352. LIST_ENTRY *listEntry;
  1353. /*
  1354. * Go through every library and find the workItem to cancel.
  1355. * This is HUGELY INEFFICIENT but this is a rare call.
  1356. * This is better than putting every request into the database.
  1357. *
  1358. * BUGBUG - this only cancels workItems that are still pending.
  1359. * what about workItems currently being processed ?
  1360. */
  1361. EnterCriticalSection(&g_globalServiceLock);
  1362. listEntry = &g_allLibrariesList;
  1363. while ((listEntry = listEntry->Flink) != &g_allLibrariesList){
  1364. LIBRARY *lib = CONTAINING_RECORD(listEntry, LIBRARY, allLibrariesListEntry);
  1365. workItem = DequeuePendingWorkItemByGuid(lib, lpRequestId);
  1366. if (workItem){
  1367. break;
  1368. }
  1369. }
  1370. LeaveCriticalSection(&g_globalServiceLock);
  1371. if (workItem){
  1372. /*
  1373. * Found the workItem to cancel.
  1374. * Dereference any objects pointed to by the workItem
  1375. * and put it back in the free list.
  1376. */
  1377. FlushWorkItem(workItem);
  1378. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1379. result = ERROR_SUCCESS;
  1380. }
  1381. else {
  1382. result = ERROR_OBJECT_NOT_FOUND;
  1383. }
  1384. }
  1385. else {
  1386. result = ERROR_INVALID_HANDLE;
  1387. }
  1388. if (result != ERROR_SUCCESS){
  1389. SetLastError(result);
  1390. }
  1391. return result;
  1392. }
  1393. DWORD WINAPI ReserveNtmsCleanerSlot( HANDLE hSession,
  1394. LPNTMS_GUID lpLibraryId,
  1395. LPNTMS_GUID lpSlotId)
  1396. {
  1397. HRESULT result;
  1398. if (ValidateSessionHandle(hSession)){
  1399. SESSION *thisSession = (SESSION *)hSession;
  1400. LIBRARY *lib;
  1401. lib = FindLibrary(lpLibraryId);
  1402. if (lib){
  1403. SLOT *slot;
  1404. slot = FindLibrarySlot(lib, lpSlotId);
  1405. if (slot){
  1406. /*
  1407. * To be reserved as the cleaner slot, the slot must
  1408. * be empty and the library must have no cleaner slot reserved.
  1409. * Redundant calls to reserve the same cleaner slot fail.
  1410. */
  1411. EnterCriticalSection(&lib->lock);
  1412. if (lib->cleanerSlotIndex == NO_SLOT_INDEX){
  1413. ASSERT(!slot->isCleanerSlot);
  1414. if (slot->insertedMedia){
  1415. result = ERROR_RESOURCE_NOT_AVAILABLE; // BUGBUG ERROR_SLOT_FULL; not defined
  1416. }
  1417. else {
  1418. lib->cleanerSlotIndex = slot->slotIndex;
  1419. slot->isCleanerSlot = TRUE;
  1420. result = ERROR_SUCCESS;
  1421. }
  1422. }
  1423. else {
  1424. result = ERROR_CLEANER_SLOT_SET;
  1425. }
  1426. LeaveCriticalSection(&lib->lock);
  1427. DerefObject(slot);
  1428. }
  1429. else {
  1430. result = ERROR_INVALID_HANDLE; // BUGBUG ERROR_INVALID_SLOT not defined
  1431. }
  1432. DerefObject(lib);
  1433. }
  1434. else {
  1435. result = ERROR_INVALID_LIBRARY;
  1436. }
  1437. }
  1438. else {
  1439. result = ERROR_INVALID_HANDLE;
  1440. }
  1441. if (result != ERROR_SUCCESS){
  1442. SetLastError(result);
  1443. }
  1444. return result;
  1445. }
  1446. DWORD WINAPI ReleaseNtmsCleanerSlot(HANDLE hSession, LPNTMS_GUID lpLibraryId)
  1447. {
  1448. HRESULT result;
  1449. if (ValidateSessionHandle(hSession)){
  1450. SESSION *thisSession = (SESSION *)hSession;
  1451. LIBRARY *lib;
  1452. lib = FindLibrary(lpLibraryId);
  1453. if (lib){
  1454. if (lib->cleanerSlotIndex == NO_SLOT_INDEX){
  1455. /*
  1456. * There is no cleaner slot configured.
  1457. */
  1458. result = ERROR_CLEANER_SLOT_NOT_SET;
  1459. }
  1460. else {
  1461. SLOT *slot;
  1462. ASSERT(lib->cleanerSlotIndex < lib->numSlots);
  1463. slot = &lib->slots[lib->cleanerSlotIndex];
  1464. ASSERT(slot->isCleanerSlot);
  1465. if (slot->insertedMedia){
  1466. result = ERROR_RESOURCE_NOT_AVAILABLE; // BUGBUG ERROR_SLOT_FULL; not defined
  1467. }
  1468. else {
  1469. slot->isCleanerSlot = FALSE;
  1470. lib->cleanerSlotIndex = NO_SLOT_INDEX;
  1471. result = ERROR_SUCCESS;
  1472. }
  1473. }
  1474. DerefObject(lib);
  1475. }
  1476. else {
  1477. result = ERROR_INVALID_LIBRARY;
  1478. }
  1479. }
  1480. else {
  1481. result = ERROR_INVALID_HANDLE;
  1482. }
  1483. if (result != ERROR_SUCCESS){
  1484. SetLastError(result);
  1485. }
  1486. return result;
  1487. }
  1488. DWORD WINAPI InjectNtmsCleaner( HANDLE hSession,
  1489. LPNTMS_GUID lpLibraryId,
  1490. LPNTMS_GUID lpInjectOperation,
  1491. DWORD dwNumberOfCleansLeft,
  1492. DWORD dwAction)
  1493. {
  1494. HRESULT result;
  1495. if (ValidateSessionHandle(hSession)){
  1496. SESSION *thisSession = (SESSION *)hSession;
  1497. LIBRARY *lib;
  1498. lib = FindLibrary(lpLibraryId);
  1499. if (lib){
  1500. EnterCriticalSection(&lib->lock);
  1501. /*
  1502. * The library must have a designated cleaner slot index reserved
  1503. * in order to receive the cleaner.
  1504. *
  1505. * BUGBUG - move all these checks to the lib thread.
  1506. */
  1507. if (lib->cleanerSlotIndex == NO_SLOT_INDEX){
  1508. result = ERROR_CLEANER_SLOT_NOT_SET;
  1509. }
  1510. else {
  1511. SLOT *slot = &lib->slots[lib->cleanerSlotIndex];
  1512. ASSERT(lib->cleanerSlotIndex < lib->numSlots);
  1513. ASSERT(slot->isCleanerSlot);
  1514. if (slot->insertedMedia){
  1515. result = ERROR_RESOURCE_NOT_AVAILABLE; // BUGBUG ERROR_SLOT_FULL; not defined
  1516. }
  1517. else {
  1518. if (dwAction == NTMS_INJECT_START){
  1519. WORKITEM *workItem;
  1520. workItem = DequeueFreeWorkItem(lib, TRUE);
  1521. if (workItem){
  1522. /*
  1523. * Build the workItem.
  1524. */
  1525. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1526. workItem->currentOp.opcode = NTMS_LM_INJECTCLEANER;
  1527. workItem->currentOp.lParam = dwNumberOfCleansLeft;
  1528. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1529. /*
  1530. * Give this workItem to the library and wake up the library thread.
  1531. */
  1532. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1533. /*
  1534. * When we enqueued the workItem in the pending queue,
  1535. * it got assigned a requestGuid. Since we're holding the
  1536. * library lock, that workItem hasn't gone anywhere yet.
  1537. * So its ok to read out the requestGuid from the workItem.
  1538. */
  1539. *lpInjectOperation = workItem->currentOp.requestGuid;
  1540. /*
  1541. * Wait for the request to be processed by the library thread.
  1542. * Note: The workItem will complete as soon as the library thread
  1543. * starts the injection. The app may cancel the cleaner
  1544. * injection using NTMS_INJECT_STOP and the returned GUID.
  1545. * BUGBUG ?
  1546. */
  1547. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1548. /*
  1549. * Get result from the completed workItem.
  1550. */
  1551. result = workItem->currentOp.resultStatus;
  1552. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1553. }
  1554. else {
  1555. result = ERROR_NOT_ENOUGH_MEMORY;
  1556. }
  1557. }
  1558. else if (dwAction == NTMS_INJECT_STOP){
  1559. result = StopCleanerInjection(lib, lpInjectOperation);
  1560. }
  1561. else {
  1562. result = ERROR_INVALID_PARAMETER;
  1563. }
  1564. }
  1565. }
  1566. LeaveCriticalSection(&lib->lock);
  1567. DerefObject(lib);
  1568. }
  1569. else {
  1570. result = ERROR_INVALID_LIBRARY;
  1571. }
  1572. }
  1573. else {
  1574. result = ERROR_INVALID_HANDLE;
  1575. }
  1576. if (result != ERROR_SUCCESS){
  1577. SetLastError(result);
  1578. }
  1579. return result;
  1580. }
  1581. DWORD WINAPI EjectNtmsCleaner( HANDLE hSession,
  1582. LPNTMS_GUID lpLibraryId,
  1583. LPNTMS_GUID lpEjectOperation,
  1584. DWORD dwAction)
  1585. {
  1586. HRESULT result;
  1587. if (ValidateSessionHandle(hSession)){
  1588. SESSION *thisSession = (SESSION *)hSession;
  1589. LIBRARY *lib;
  1590. lib = FindLibrary(lpLibraryId);
  1591. if (lib){
  1592. EnterCriticalSection(&lib->lock);
  1593. if (dwAction == NTMS_EJECT_START){
  1594. WORKITEM *workItem;
  1595. workItem = DequeueFreeWorkItem(lib, TRUE);
  1596. if (workItem){
  1597. /*
  1598. * Build the workItem.
  1599. */
  1600. RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
  1601. workItem->currentOp.opcode = NTMS_LM_EJECTCLEANER;
  1602. workItem->currentOp.resultStatus = ERROR_IO_PENDING;
  1603. /*
  1604. * Give this workItem to the library and wake up the library thread.
  1605. */
  1606. EnqueuePendingWorkItem(workItem->owningLib, workItem);
  1607. /*
  1608. * When we enqueued the workItem in the pending queue,
  1609. * it got assigned a requestGuid. Since we're holding the
  1610. * library lock, that workItem hasn't gone anywhere yet.
  1611. * So its ok to read out the requestGuid from the workItem.
  1612. */
  1613. *lpEjectOperation = workItem->currentOp.requestGuid;
  1614. /*
  1615. * Wait for the request to be processed by the library thread.
  1616. * Note: The workItem will complete as soon as the library thread
  1617. * starts the ejection. The app may cancel the cleaner
  1618. * ejection using NTMS_EJECT_STOP and the returned GUID.
  1619. * BUGBUG ?
  1620. */
  1621. WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
  1622. /*
  1623. * Get result from the completed workItem.
  1624. */
  1625. result = workItem->currentOp.resultStatus;
  1626. EnqueueFreeWorkItem(workItem->owningLib, workItem);
  1627. }
  1628. else {
  1629. result = ERROR_NOT_ENOUGH_MEMORY;
  1630. }
  1631. }
  1632. else if (dwAction == NTMS_EJECT_STOP){
  1633. result = StopCleanerEjection(lib, lpEjectOperation);
  1634. }
  1635. else {
  1636. result = ERROR_INVALID_PARAMETER;
  1637. }
  1638. LeaveCriticalSection(&lib->lock);
  1639. DerefObject(lib);
  1640. }
  1641. else {
  1642. result = ERROR_INVALID_LIBRARY;
  1643. }
  1644. }
  1645. else {
  1646. result = ERROR_INVALID_HANDLE;
  1647. }
  1648. if (result != ERROR_SUCCESS){
  1649. SetLastError(result);
  1650. }
  1651. return result;
  1652. }
  1653. DWORD WINAPI DeleteNtmsLibrary(HANDLE hSession, LPNTMS_GUID lpLibraryId)
  1654. {
  1655. HRESULT result;
  1656. if (ValidateSessionHandle(hSession)){
  1657. SESSION *thisSession = (SESSION *)hSession;
  1658. LIBRARY *lib;
  1659. lib = FindLibrary(lpLibraryId);
  1660. if (lib){
  1661. result = DeleteLibrary(lib);
  1662. /*
  1663. * Dereference the library due to the reference that happened
  1664. * when we called FindLibrary. The library will get deleted
  1665. * once all references go away.
  1666. */
  1667. DerefObject(lib);
  1668. }
  1669. else {
  1670. result = ERROR_INVALID_LIBRARY;
  1671. }
  1672. }
  1673. else {
  1674. result = ERROR_INVALID_HANDLE;
  1675. }
  1676. if (result != ERROR_SUCCESS){
  1677. SetLastError(result);
  1678. }
  1679. return result;
  1680. }
  1681. DWORD WINAPI DeleteNtmsDrive(HANDLE hSession, LPNTMS_GUID lpDriveId)
  1682. {
  1683. HRESULT result;
  1684. if (ValidateSessionHandle(hSession)){
  1685. SESSION *thisSession = (SESSION *)hSession;
  1686. DRIVE *drive;
  1687. drive = FindDrive(lpDriveId);
  1688. if (drive){
  1689. result = DeleteDrive(drive);
  1690. /*
  1691. * Dereference the drive due to the reference that happened
  1692. * when we called FindDrive. The drive will get deleted
  1693. * once all references go away.
  1694. */
  1695. DerefObject(drive);
  1696. }
  1697. else {
  1698. result = ERROR_INVALID_DRIVE;
  1699. }
  1700. }
  1701. else {
  1702. result = ERROR_INVALID_HANDLE;
  1703. }
  1704. if (result != ERROR_SUCCESS){
  1705. SetLastError(result);
  1706. }
  1707. return result;
  1708. }
  1709. DWORD WINAPI GetNtmsRequestOrder( HANDLE hSession,
  1710. LPNTMS_GUID lpRequestId,
  1711. LPDWORD lpdwOrderNumber)
  1712. {
  1713. HRESULT result;
  1714. if (ValidateSessionHandle(hSession)){
  1715. SESSION *thisSession = (SESSION *)hSession;
  1716. if (lpRequestId){
  1717. LIST_ENTRY *listEntry;
  1718. result = ERROR_INVALID_HANDLE;
  1719. *lpdwOrderNumber = 0;
  1720. EnterCriticalSection(&g_globalServiceLock);
  1721. /*
  1722. * Go through every library and find the pending workItem.
  1723. * This is HUGELY INEFFICIENT but this is a rare call.
  1724. * This is better than putting every request into the database.
  1725. */
  1726. listEntry = &g_allLibrariesList;
  1727. while ((listEntry = listEntry->Flink) != &g_allLibrariesList){
  1728. LIBRARY *lib = CONTAINING_RECORD(listEntry, LIBRARY, allLibrariesListEntry);
  1729. LIST_ENTRY *listEntry2;
  1730. ULONG requestOrder = 1;
  1731. EnterCriticalSection(&lib->lock);
  1732. listEntry2 = &lib->pendingWorkItemsList;
  1733. while ((listEntry2 = listEntry2->Flink) != &lib->pendingWorkItemsList){
  1734. WORKITEM *workItem = CONTAINING_RECORD(listEntry2, WORKITEM, libListEntry);
  1735. if (RtlEqualMemory(&workItem->currentOp.requestGuid, lpRequestId, sizeof(NTMS_GUID))){
  1736. *lpdwOrderNumber = requestOrder;
  1737. result = ERROR_SUCCESS;
  1738. break;
  1739. }
  1740. else {
  1741. requestOrder++;
  1742. }
  1743. }
  1744. LeaveCriticalSection(&lib->lock);
  1745. if (result == ERROR_SUCCESS){
  1746. break;
  1747. }
  1748. }
  1749. LeaveCriticalSection(&g_globalServiceLock);
  1750. }
  1751. else {
  1752. result = ERROR_INVALID_HANDLE;
  1753. }
  1754. }
  1755. else {
  1756. result = ERROR_INVALID_HANDLE;
  1757. }
  1758. if (result != ERROR_SUCCESS){
  1759. SetLastError(result);
  1760. }
  1761. return result;
  1762. }
  1763. DWORD WINAPI SetNtmsRequestOrder( HANDLE hSession,
  1764. LPNTMS_GUID lpRequestId,
  1765. DWORD dwOrderNumber)
  1766. {
  1767. HRESULT result;
  1768. if (ValidateSessionHandle(hSession)){
  1769. SESSION *thisSession = (SESSION *)hSession;
  1770. // BUGBUG FINISH
  1771. result = ERROR_SUCCESS;
  1772. }
  1773. else {
  1774. result = ERROR_INVALID_HANDLE;
  1775. }
  1776. if (result != ERROR_SUCCESS){
  1777. SetLastError(result);
  1778. }
  1779. return result;
  1780. }
  1781. DWORD WINAPI DeleteNtmsRequests(HANDLE hSession,
  1782. LPNTMS_GUID lpRequestId,
  1783. DWORD dwType,
  1784. DWORD dwCount)
  1785. {
  1786. HRESULT result;
  1787. if (ValidateSessionHandle(hSession)){
  1788. SESSION *thisSession = (SESSION *)hSession;
  1789. // BUGBUG FINISH
  1790. result = ERROR_SUCCESS;
  1791. }
  1792. else {
  1793. result = ERROR_INVALID_HANDLE;
  1794. }
  1795. if (result != ERROR_SUCCESS){
  1796. SetLastError(result);
  1797. }
  1798. return result;
  1799. }
  1800. DWORD WINAPI BeginNtmsDeviceChangeDetection(HANDLE hSession, LPHANDLE lpDetectHandle)
  1801. {
  1802. HRESULT result;
  1803. if (ValidateSessionHandle(hSession)){
  1804. SESSION *thisSession = (SESSION *)hSession;
  1805. // BUGBUG FINISH
  1806. result = ERROR_SUCCESS;
  1807. }
  1808. else {
  1809. result = ERROR_INVALID_HANDLE;
  1810. }
  1811. if (result != ERROR_SUCCESS){
  1812. SetLastError(result);
  1813. }
  1814. return result;
  1815. }
  1816. DWORD WINAPI SetNtmsDeviceChangeDetection( HANDLE hSession,
  1817. HANDLE DetectHandle,
  1818. LPNTMS_GUID lpRequestId,
  1819. DWORD dwType,
  1820. DWORD dwCount)
  1821. {
  1822. HRESULT result;
  1823. if (ValidateSessionHandle(hSession)){
  1824. SESSION *thisSession = (SESSION *)hSession;
  1825. // BUGBUG FINISH
  1826. result = ERROR_SUCCESS;
  1827. }
  1828. else {
  1829. result = ERROR_INVALID_HANDLE;
  1830. }
  1831. if (result != ERROR_SUCCESS){
  1832. SetLastError(result);
  1833. }
  1834. return result;
  1835. }
  1836. DWORD WINAPI EndNtmsDeviceChangeDetection(HANDLE hSession, HANDLE DetectHandle)
  1837. {
  1838. HRESULT result;
  1839. if (ValidateSessionHandle(hSession)){
  1840. SESSION *thisSession = (SESSION *)hSession;
  1841. // BUGBUG FINISH
  1842. result = ERROR_SUCCESS;
  1843. }
  1844. else {
  1845. result = ERROR_INVALID_HANDLE;
  1846. }
  1847. if (result != ERROR_SUCCESS){
  1848. SetLastError(result);
  1849. }
  1850. return result;
  1851. }
  1852. /******** BUGBUG: INtmsObjectManagement1 APIs *********************/
  1853. DWORD WINAPI GetNtmsObjectSecurity( HANDLE hSession,
  1854. LPNTMS_GUID lpObjectId,
  1855. DWORD dwType,
  1856. SECURITY_INFORMATION RequestedInformation,
  1857. PSECURITY_DESCRIPTOR lpSecurityDescriptor,
  1858. DWORD nLength,
  1859. LPDWORD lpnLengthNeeded)
  1860. {
  1861. HRESULT result;
  1862. if (ValidateSessionHandle(hSession)){
  1863. SESSION *thisSession = (SESSION *)hSession;
  1864. // BUGBUG FINISH
  1865. result = ERROR_SUCCESS;
  1866. }
  1867. else {
  1868. result = ERROR_INVALID_HANDLE;
  1869. }
  1870. if (result != ERROR_SUCCESS){
  1871. SetLastError(result);
  1872. }
  1873. return result;
  1874. }
  1875. DWORD WINAPI SetNtmsObjectSecurity( HANDLE hSession,
  1876. LPNTMS_GUID lpObjectId,
  1877. DWORD dwType,
  1878. SECURITY_INFORMATION SecurityInformation,
  1879. PSECURITY_DESCRIPTOR lpSecurityDescriptor)
  1880. {
  1881. HRESULT result;
  1882. if (ValidateSessionHandle(hSession)){
  1883. SESSION *thisSession = (SESSION *)hSession;
  1884. // BUGBUG FINISH
  1885. result = ERROR_SUCCESS;
  1886. }
  1887. else {
  1888. result = ERROR_INVALID_HANDLE;
  1889. }
  1890. if (result != ERROR_SUCCESS){
  1891. SetLastError(result);
  1892. }
  1893. return result;
  1894. }
  1895. DWORD WINAPI GetNtmsObjectAttributeW( HANDLE hSession,
  1896. LPNTMS_GUID lpObjectId,
  1897. DWORD dwType,
  1898. LPCWSTR lpAttributeName,
  1899. LPVOID lpAttributeData,
  1900. LPDWORD lpAttributeSize)
  1901. {
  1902. HRESULT result;
  1903. if (ValidateSessionHandle(hSession)){
  1904. SESSION *thisSession = (SESSION *)hSession;
  1905. // BUGBUG FINISH
  1906. result = ERROR_SUCCESS;
  1907. }
  1908. else {
  1909. result = ERROR_INVALID_HANDLE;
  1910. }
  1911. if (result != ERROR_SUCCESS){
  1912. SetLastError(result);
  1913. }
  1914. return result;
  1915. }
  1916. DWORD WINAPI GetNtmsObjectAttributeA( HANDLE hSession,
  1917. LPNTMS_GUID lpObjectId,
  1918. DWORD dwType,
  1919. LPCSTR lpAttributeName,
  1920. LPVOID lpAttributeData,
  1921. LPDWORD lpAttributeSize)
  1922. {
  1923. HRESULT result;
  1924. WCHAR wAttributeName[NTMS_OBJECTNAME_LENGTH];
  1925. AsciiToWChar(wAttributeName, lpAttributeName, NTMS_OBJECTNAME_LENGTH);
  1926. result = GetNtmsObjectAttributeW( hSession,
  1927. lpObjectId,
  1928. dwType,
  1929. wAttributeName,
  1930. lpAttributeData,
  1931. lpAttributeSize);
  1932. if (result != ERROR_SUCCESS){
  1933. SetLastError(result);
  1934. }
  1935. return result;
  1936. }
  1937. DWORD WINAPI SetNtmsObjectAttributeA( HANDLE hSession,
  1938. LPNTMS_GUID lpObjectId,
  1939. DWORD dwType,
  1940. LPCSTR lpAttributeName,
  1941. LPVOID lpAttributeData,
  1942. DWORD dwAttributeSize)
  1943. {
  1944. HRESULT result;
  1945. WCHAR wAttributeName[NTMS_OBJECTNAME_LENGTH];
  1946. AsciiToWChar(wAttributeName, lpAttributeName, NTMS_OBJECTNAME_LENGTH);
  1947. result = SetNtmsObjectAttributeW( hSession,
  1948. lpObjectId,
  1949. dwType,
  1950. wAttributeName,
  1951. lpAttributeData,
  1952. dwAttributeSize);
  1953. if (result != ERROR_SUCCESS){
  1954. SetLastError(result);
  1955. }
  1956. return result;
  1957. }
  1958. DWORD WINAPI SetNtmsObjectAttributeW( HANDLE hSession,
  1959. LPNTMS_GUID lpObjectId,
  1960. DWORD dwType,
  1961. LPCWSTR lpAttributeName,
  1962. LPVOID lpAttributeData,
  1963. DWORD AttributeSize)
  1964. {
  1965. HRESULT result;
  1966. if (ValidateSessionHandle(hSession)){
  1967. SESSION *thisSession = (SESSION *)hSession;
  1968. // BUGBUG FINISH
  1969. result = ERROR_SUCCESS;
  1970. }
  1971. else {
  1972. result = ERROR_INVALID_HANDLE;
  1973. }
  1974. if (result != ERROR_SUCCESS){
  1975. SetLastError(result);
  1976. }
  1977. return result;
  1978. }
  1979. DWORD WINAPI EnumerateNtmsObject( HANDLE hSession,
  1980. const LPNTMS_GUID lpContainerId,
  1981. LPNTMS_GUID lpList,
  1982. LPDWORD lpdwListSize,
  1983. DWORD dwType,
  1984. DWORD dwOptions)
  1985. {
  1986. HRESULT result;
  1987. if (ValidateSessionHandle(hSession)){
  1988. SESSION *thisSession = (SESSION *)hSession;
  1989. // BUGBUG FINISH
  1990. result = ERROR_SUCCESS;
  1991. }
  1992. else {
  1993. result = ERROR_INVALID_HANDLE;
  1994. }
  1995. if (result != ERROR_SUCCESS){
  1996. SetLastError(result);
  1997. }
  1998. return result;
  1999. }
  2000. DWORD WINAPI EnableNtmsObject(HANDLE hSession, DWORD dwType, LPNTMS_GUID lpObjectId)
  2001. {
  2002. HRESULT result;
  2003. if (ValidateSessionHandle(hSession)){
  2004. SESSION *thisSession = (SESSION *)hSession;
  2005. // BUGBUG FINISH
  2006. result = ERROR_SUCCESS;
  2007. }
  2008. else {
  2009. result = ERROR_INVALID_HANDLE;
  2010. }
  2011. if (result != ERROR_SUCCESS){
  2012. SetLastError(result);
  2013. }
  2014. return result;
  2015. }
  2016. DWORD WINAPI DisableNtmsObject(HANDLE hSession, DWORD dwType, LPNTMS_GUID lpObjectId)
  2017. {
  2018. HRESULT result;
  2019. if (ValidateSessionHandle(hSession)){
  2020. SESSION *thisSession = (SESSION *)hSession;
  2021. // BUGBUG FINISH
  2022. result = ERROR_SUCCESS;
  2023. }
  2024. else {
  2025. result = ERROR_INVALID_HANDLE;
  2026. }
  2027. if (result != ERROR_SUCCESS){
  2028. SetLastError(result);
  2029. }
  2030. return result;
  2031. }
  2032. /******* BUGBUG: INtmsObjectInfo1 APIs ****************************/
  2033. // BUGBUG - these 4 functions have another form with type,size as last args
  2034. HRESULT WINAPI GetNtmsServerObjectInformationW( HANDLE hSession,
  2035. LPNTMS_GUID lpObjectId,
  2036. LPNTMS_OBJECTINFORMATIONW lpInfo,
  2037. int revision)
  2038. {
  2039. HRESULT result;
  2040. if (ValidateSessionHandle(hSession)){
  2041. SESSION *thisSession = (SESSION *)hSession;
  2042. // BUGBUG FINISH
  2043. result = ERROR_SUCCESS;
  2044. }
  2045. else {
  2046. result = ERROR_INVALID_HANDLE;
  2047. }
  2048. if (result != ERROR_SUCCESS){
  2049. SetLastError(result);
  2050. }
  2051. return result;
  2052. }
  2053. HRESULT WINAPI GetNtmsServerObjectInformationA( HANDLE hSession,
  2054. LPNTMS_GUID lpObjectId,
  2055. LPNTMS_OBJECTINFORMATIONA lpInfo,
  2056. int revision)
  2057. {
  2058. HRESULT result;
  2059. if (lpInfo){
  2060. NTMS_OBJECTINFORMATIONW wObjInfo;
  2061. ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
  2062. result = GetNtmsServerObjectInformationW(hSession, lpObjectId, &wObjInfo, revision);
  2063. }
  2064. else {
  2065. result = ERROR_INVALID_PARAMETER;
  2066. }
  2067. if (result != ERROR_SUCCESS){
  2068. SetLastError(result);
  2069. }
  2070. return result;
  2071. }
  2072. HRESULT WINAPI SetNtmsServerObjectInformationW( HANDLE hSession,
  2073. LPNTMS_GUID lpObjectId,
  2074. LPNTMS_OBJECTINFORMATIONW lpInfo,
  2075. int revision)\
  2076. {
  2077. HRESULT result;
  2078. if (ValidateSessionHandle(hSession)){
  2079. SESSION *thisSession = (SESSION *)hSession;
  2080. // BUGBUG FINISH
  2081. result = ERROR_SUCCESS;
  2082. }
  2083. else {
  2084. result = ERROR_INVALID_HANDLE;
  2085. }
  2086. if (result != ERROR_SUCCESS){
  2087. SetLastError(result);
  2088. }
  2089. return result;
  2090. }
  2091. HRESULT WINAPI SetNtmsServerObjectInformationA( HANDLE hSession,
  2092. LPNTMS_GUID lpObjectId,
  2093. LPNTMS_OBJECTINFORMATIONA lpInfo,
  2094. int revision)
  2095. {
  2096. HRESULT result;
  2097. if (lpObjectId && lpInfo){
  2098. NTMS_OBJECTINFORMATIONW wObjInfo;
  2099. ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
  2100. result = SetNtmsServerObjectInformationW(hSession, lpObjectId, &wObjInfo, revision);
  2101. }
  2102. else {
  2103. result = ERROR_INVALID_PARAMETER;
  2104. }
  2105. if (result != ERROR_SUCCESS){
  2106. SetLastError(result);
  2107. }
  2108. return result;
  2109. }
  2110. DWORD WINAPI CreateNtmsMediaA( HANDLE hSession,
  2111. LPNTMS_OBJECTINFORMATIONA lpMedia,
  2112. LPNTMS_OBJECTINFORMATIONA lpList,
  2113. DWORD dwOptions)
  2114. {
  2115. HRESULT result;
  2116. if (lpMedia && lpList){
  2117. NTMS_OBJECTINFORMATIONW wObjInfoMedia, wObjInfoList;
  2118. ConvertObjectInfoAToWChar(&wObjInfoMedia, lpMedia);
  2119. ConvertObjectInfoAToWChar(&wObjInfoList, lpList);
  2120. result = CreateNtmsMediaW(hSession, &wObjInfoMedia, &wObjInfoList, dwOptions);
  2121. }
  2122. else {
  2123. result = ERROR_INVALID_PARAMETER;
  2124. }
  2125. if (result != ERROR_SUCCESS){
  2126. SetLastError(result);
  2127. }
  2128. return result;
  2129. }
  2130. DWORD WINAPI CreateNtmsMediaW( HANDLE hSession,
  2131. LPNTMS_OBJECTINFORMATIONW lpMedia,
  2132. LPNTMS_OBJECTINFORMATIONW lpList,
  2133. DWORD dwOptions)
  2134. {
  2135. HRESULT result;
  2136. if (ValidateSessionHandle(hSession)){
  2137. SESSION *thisSession = (SESSION *)hSession;
  2138. // BUGBUG FINISH
  2139. result = ERROR_SUCCESS;
  2140. }
  2141. else {
  2142. result = ERROR_INVALID_HANDLE;
  2143. }
  2144. if (result != ERROR_SUCCESS){
  2145. SetLastError(result);
  2146. }
  2147. return result;
  2148. }
  2149. DWORD WINAPI GetNtmsObjectInformationA( HANDLE hSession,
  2150. LPNTMS_GUID lpObjectId,
  2151. LPNTMS_OBJECTINFORMATIONA lpInfo)
  2152. {
  2153. HRESULT result;
  2154. if (lpInfo){
  2155. NTMS_OBJECTINFORMATIONW wObjInfo;
  2156. ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
  2157. result = GetNtmsObjectInformationW(hSession, lpObjectId, &wObjInfo);
  2158. }
  2159. else {
  2160. result = ERROR_INVALID_PARAMETER;
  2161. }
  2162. if (result != ERROR_SUCCESS){
  2163. SetLastError(result);
  2164. }
  2165. return result;
  2166. }
  2167. DWORD WINAPI GetNtmsObjectInformationW( HANDLE hSession,
  2168. LPNTMS_GUID lpObjectId,
  2169. LPNTMS_OBJECTINFORMATIONW lpInfo)
  2170. {
  2171. HRESULT result;
  2172. if (ValidateSessionHandle(hSession)){
  2173. SESSION *thisSession = (SESSION *)hSession;
  2174. if (lpObjectId && lpInfo){
  2175. // BUGBUG FINISH
  2176. result = ERROR_SUCCESS;
  2177. }
  2178. else {
  2179. result = ERROR_INVALID_PARAMETER;
  2180. }
  2181. }
  2182. else {
  2183. result = ERROR_INVALID_HANDLE;
  2184. }
  2185. if (result != ERROR_SUCCESS){
  2186. SetLastError(result);
  2187. }
  2188. return result;
  2189. }
  2190. DWORD WINAPI SetNtmsObjectInformationA( HANDLE hSession,
  2191. LPNTMS_GUID lpObjectId,
  2192. LPNTMS_OBJECTINFORMATIONA lpInfo)
  2193. {
  2194. HRESULT result;
  2195. if (lpInfo){
  2196. NTMS_OBJECTINFORMATIONW wObjInfo;
  2197. ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
  2198. result = SetNtmsObjectInformationW(hSession, lpObjectId, &wObjInfo);
  2199. }
  2200. else {
  2201. result = ERROR_INVALID_PARAMETER;
  2202. }
  2203. if (result != ERROR_SUCCESS){
  2204. SetLastError(result);
  2205. }
  2206. return result;
  2207. }
  2208. DWORD WINAPI SetNtmsObjectInformationW( HANDLE hSession,
  2209. LPNTMS_GUID lpObjectId,
  2210. LPNTMS_OBJECTINFORMATIONW lpInfo)
  2211. {
  2212. HRESULT result;
  2213. if (ValidateSessionHandle(hSession)){
  2214. SESSION *thisSession = (SESSION *)hSession;
  2215. if (lpObjectId && lpInfo){
  2216. // BUGBUG FINISH
  2217. result = ERROR_SUCCESS;
  2218. }
  2219. else {
  2220. result = ERROR_INVALID_PARAMETER;
  2221. }
  2222. }
  2223. else {
  2224. result = ERROR_INVALID_HANDLE;
  2225. }
  2226. if (result != ERROR_SUCCESS){
  2227. SetLastError(result);
  2228. }
  2229. return result;
  2230. }
  2231. HANDLE WINAPI OpenNtmsNotification(HANDLE hSession, DWORD dwType)
  2232. {
  2233. HANDLE hNotify;
  2234. if (ValidateSessionHandle(hSession)){
  2235. SESSION *thisSession = (SESSION *)hSession;
  2236. // BUGBUG FINISH
  2237. hNotify = NULL;
  2238. }
  2239. else {
  2240. SetLastError(ERROR_INVALID_HANDLE);
  2241. hNotify = NULL;
  2242. }
  2243. return hNotify;
  2244. }
  2245. DWORD WINAPI WaitForNtmsNotification( HANDLE hNotification,
  2246. LPNTMS_NOTIFICATIONINFORMATION lpNotificationInformation,
  2247. DWORD dwTimeout)
  2248. {
  2249. HRESULT result;
  2250. // BUGBUG FINISH
  2251. result = ERROR_SUCCESS;
  2252. if (result != ERROR_SUCCESS){
  2253. SetLastError(result);
  2254. }
  2255. return result;
  2256. }
  2257. DWORD WINAPI CloseNtmsNotification(HANDLE hNotification)
  2258. {
  2259. HRESULT result;
  2260. // BUGBUG FINISH
  2261. result = ERROR_SUCCESS;
  2262. if (result != ERROR_SUCCESS){
  2263. SetLastError(result);
  2264. }
  2265. return result;
  2266. }
  2267. DWORD WINAPI EjectDiskFromSADriveA( LPCSTR lpComputerName,
  2268. LPCSTR lpAppName,
  2269. LPCSTR lpDeviceName,
  2270. HWND hWnd,
  2271. LPCSTR lpTitle,
  2272. LPCSTR lpMessage,
  2273. DWORD dwOptions)
  2274. {
  2275. HRESULT result;
  2276. // BUGBUG FINISH
  2277. result = ERROR_SUCCESS;
  2278. if (result != ERROR_SUCCESS){
  2279. SetLastError(result);
  2280. }
  2281. return result;
  2282. }
  2283. DWORD WINAPI EjectDiskFromSADriveW( LPCWSTR lpComputerName,
  2284. LPCWSTR lpAppName,
  2285. LPCWSTR lpDeviceName,
  2286. HWND hWnd,
  2287. LPCWSTR lpTitle,
  2288. LPCWSTR lpMessage,
  2289. DWORD dwOptions)
  2290. {
  2291. HRESULT result;
  2292. // BUGBUG FINISH
  2293. result = ERROR_SUCCESS;
  2294. if (result != ERROR_SUCCESS){
  2295. SetLastError(result);
  2296. }
  2297. return result;
  2298. }
  2299. DWORD WINAPI GetVolumesFromDriveA( LPSTR pszDriveName,
  2300. LPSTR* VolumeNameBufferPtr,
  2301. LPSTR* DriveLetterBufferPtr)
  2302. {
  2303. HRESULT result;
  2304. // BUGBUG FINISH
  2305. result = ERROR_SUCCESS;
  2306. if (result != ERROR_SUCCESS){
  2307. SetLastError(result);
  2308. }
  2309. return result;
  2310. }
  2311. DWORD WINAPI GetVolumesFromDriveW( LPWSTR pszDriveName,
  2312. LPWSTR *VolumeNameBufferPtr,
  2313. LPWSTR *DriveLetterBufferPtr)
  2314. {
  2315. HRESULT result;
  2316. // BUGBUG FINISH
  2317. result = ERROR_SUCCESS;
  2318. if (result != ERROR_SUCCESS){
  2319. SetLastError(result);
  2320. }
  2321. return result;
  2322. }
  2323. DWORD WINAPI IdentifyNtmsSlot(HANDLE hSession, LPNTMS_GUID lpSlotId, DWORD dwOption)
  2324. {
  2325. HRESULT result;
  2326. if (ValidateSessionHandle(hSession)){
  2327. SESSION *thisSession = (SESSION *)hSession;
  2328. // BUGBUG FINISH
  2329. result = ERROR_SUCCESS;
  2330. }
  2331. else {
  2332. result = ERROR_INVALID_HANDLE;
  2333. }
  2334. if (result != ERROR_SUCCESS){
  2335. SetLastError(result);
  2336. }
  2337. return result;
  2338. }
  2339. DWORD WINAPI GetNtmsUIOptionsA( HANDLE hSession,
  2340. const LPNTMS_GUID lpObjectId,
  2341. DWORD dwType,
  2342. LPSTR lpszDestination,
  2343. LPDWORD lpAttributeSize)
  2344. {
  2345. HRESULT result;
  2346. if (ValidateSessionHandle(hSession)){
  2347. SESSION *thisSession = (SESSION *)hSession;
  2348. // BUGBUG FINISH
  2349. result = ERROR_SUCCESS;
  2350. }
  2351. else {
  2352. result = ERROR_INVALID_HANDLE;
  2353. }
  2354. if (result != ERROR_SUCCESS){
  2355. SetLastError(result);
  2356. }
  2357. return result;
  2358. }
  2359. DWORD WINAPI GetNtmsUIOptionsW( HANDLE hSession,
  2360. const LPNTMS_GUID lpObjectId,
  2361. DWORD dwType,
  2362. LPWSTR lpszDestination,
  2363. LPDWORD lpdwSize)
  2364. {
  2365. HRESULT result;
  2366. if (ValidateSessionHandle(hSession)){
  2367. SESSION *thisSession = (SESSION *)hSession;
  2368. // BUGBUG FINISH
  2369. result = ERROR_SUCCESS;
  2370. }
  2371. else {
  2372. result = ERROR_INVALID_HANDLE;
  2373. }
  2374. if (result != ERROR_SUCCESS){
  2375. SetLastError(result);
  2376. }
  2377. return result;
  2378. }
  2379. DWORD WINAPI SetNtmsUIOptionsA( HANDLE hSession,
  2380. const LPNTMS_GUID lpObjectId,
  2381. DWORD dwType,
  2382. DWORD dwOperation,
  2383. LPCSTR lpszDestination)
  2384. {
  2385. HRESULT result;
  2386. if (ValidateSessionHandle(hSession)){
  2387. SESSION *thisSession = (SESSION *)hSession;
  2388. // BUGBUG FINISH
  2389. result = ERROR_SUCCESS;
  2390. }
  2391. else {
  2392. result = ERROR_INVALID_HANDLE;
  2393. }
  2394. if (result != ERROR_SUCCESS){
  2395. SetLastError(result);
  2396. }
  2397. return result;
  2398. }
  2399. DWORD WINAPI SetNtmsUIOptionsW( HANDLE hSession,
  2400. const LPNTMS_GUID lpObjectId,
  2401. DWORD dwType,
  2402. DWORD dwOperation,
  2403. LPCWSTR lpszDestination)
  2404. {
  2405. HRESULT result;
  2406. if (ValidateSessionHandle(hSession)){
  2407. SESSION *thisSession = (SESSION *)hSession;
  2408. // BUGBUG FINISH
  2409. result = ERROR_SUCCESS;
  2410. }
  2411. else {
  2412. result = ERROR_INVALID_HANDLE;
  2413. }
  2414. if (result != ERROR_SUCCESS){
  2415. SetLastError(result);
  2416. }
  2417. return result;
  2418. }