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
2998 lines
87 KiB
/*
|
|
* NTMSAPI.C
|
|
*
|
|
* RSM Service : Service API
|
|
*
|
|
* Author: ErvinP
|
|
*
|
|
* (c) 2001 Microsoft Corporation
|
|
*
|
|
*/
|
|
|
|
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <wtypes.h>
|
|
|
|
#include <ntmsapi.h>
|
|
#include "internal.h"
|
|
#include "resource.h"
|
|
#include "debug.h"
|
|
|
|
|
|
// BUGBUG - these need to be exposed as a COM interface w/ RPC
|
|
|
|
|
|
HANDLE WINAPI OpenNtmsServerSessionW( LPCWSTR lpServer,
|
|
LPCWSTR lpApplication,
|
|
LPCWSTR lpClientName,
|
|
LPCWSTR lpUserName,
|
|
DWORD dwOptions,
|
|
LPVOID lpConnectionContext)
|
|
{
|
|
SESSION *newSession;
|
|
|
|
newSession = NewSession(lpServer, lpApplication, lpClientName, lpUserName);
|
|
if (newSession){
|
|
}
|
|
else {
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
return (HANDLE)newSession;
|
|
}
|
|
|
|
|
|
HANDLE WINAPI OpenNtmsServerSessionA( LPCSTR lpServer,
|
|
LPCSTR lpApplication,
|
|
LPCSTR lpClientName,
|
|
LPCSTR lpUserName,
|
|
DWORD dwOptions,
|
|
LPVOID lpConnectionContext)
|
|
{
|
|
SESSION *newSession;
|
|
WCHAR wServerName[NTMS_COMPUTERNAME_LENGTH];
|
|
WCHAR wAppName[NTMS_APPLICATIONNAME_LENGTH];
|
|
WCHAR wClientName[NTMS_COMPUTERNAME_LENGTH];
|
|
WCHAR wUserName[NTMS_USERNAME_LENGTH];
|
|
|
|
AsciiToWChar(wServerName, lpServer, NTMS_COMPUTERNAME_LENGTH);
|
|
AsciiToWChar(wAppName, lpApplication, NTMS_APPLICATIONNAME_LENGTH);
|
|
AsciiToWChar(wClientName, lpClientName, NTMS_COMPUTERNAME_LENGTH);
|
|
AsciiToWChar(wUserName, lpUserName, NTMS_USERNAME_LENGTH);
|
|
|
|
newSession = OpenNtmsServerSessionW( wServerName,
|
|
wAppName,
|
|
wClientName,
|
|
wUserName,
|
|
dwOptions,
|
|
lpConnectionContext);
|
|
|
|
return newSession;
|
|
|
|
}
|
|
|
|
|
|
DWORD WINAPI CloseNtmsSession(HANDLE hSession)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
FreeSession(thisSession);
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SubmitNtmsOperatorRequestW( HANDLE hSession,
|
|
DWORD dwRequest,
|
|
LPCWSTR lpMessage,
|
|
LPNTMS_GUID lpArg1Id,
|
|
LPNTMS_GUID lpArg2Id,
|
|
LPNTMS_GUID lpRequestId)
|
|
{
|
|
HRESULT result = ERROR_SUCCESS;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
switch (dwRequest){
|
|
|
|
case NTMS_OPREQ_DEVICESERVICE:
|
|
case NTMS_OPREQ_MOVEMEDIA:
|
|
case NTMS_OPREQ_NEWMEDIA:
|
|
if (!lpArg1Id){
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
break;
|
|
|
|
case NTMS_OPREQ_CLEANER:
|
|
case NTMS_OPREQ_MESSAGE:
|
|
break;
|
|
|
|
default:
|
|
DBGERR(("SubmitNtmsOperatorRequestW: unrecognized request"));
|
|
result = ERROR_NOT_SUPPORTED;
|
|
break;
|
|
|
|
}
|
|
|
|
if (result == ERROR_SUCCESS){
|
|
OPERATOR_REQUEST *opReq;
|
|
|
|
opReq = NewOperatorRequest(dwRequest, lpMessage, lpArg1Id, lpArg2Id);
|
|
if (opReq){
|
|
|
|
/*
|
|
* Retrieve the localized RSM message for this op request.
|
|
*/
|
|
switch (dwRequest){
|
|
case NTMS_OPREQ_DEVICESERVICE:
|
|
LoadStringW(g_hInstance, IDS_OPREQUESTDEVICESVC, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
|
|
break;
|
|
case NTMS_OPREQ_MOVEMEDIA:
|
|
LoadStringW(g_hInstance, IDS_OPREQUESTMOVEMEDIA, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
|
|
break;
|
|
case NTMS_OPREQ_NEWMEDIA:
|
|
LoadStringW(g_hInstance, IDS_OPREQUESTNEWMEDIA, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
|
|
break;
|
|
case NTMS_OPREQ_CLEANER:
|
|
LoadStringW(g_hInstance, IDS_OPREQUESTCLEANER, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
|
|
break;
|
|
case NTMS_OPREQ_MESSAGE:
|
|
LoadStringW(g_hInstance, IDS_OPREQUESTMESSAGE, opReq->rsmMessage, sizeof(opReq->rsmMessage)/sizeof(WCHAR));
|
|
break;
|
|
}
|
|
|
|
*lpRequestId = opReq->opReqGuid;
|
|
|
|
if (EnqueueOperatorRequest(thisSession, opReq)){
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
FreeOperatorRequest(opReq);
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SubmitNtmsOperatorRequestA( HANDLE hSession,
|
|
DWORD dwRequest,
|
|
LPCSTR lpMessage,
|
|
LPNTMS_GUID lpArg1Id,
|
|
LPNTMS_GUID lpArg2Id,
|
|
LPNTMS_GUID lpRequestId)
|
|
{
|
|
WCHAR wMessage[NTMS_MESSAGE_LENGTH];
|
|
HRESULT result;
|
|
|
|
AsciiToWChar(wMessage, lpMessage, NTMS_MESSAGE_LENGTH);
|
|
result = SubmitNtmsOperatorRequestW(hSession,
|
|
dwRequest,
|
|
wMessage,
|
|
lpArg1Id,
|
|
lpArg2Id,
|
|
lpRequestId);
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI WaitForNtmsOperatorRequest( HANDLE hSession,
|
|
LPNTMS_GUID lpRequestId,
|
|
DWORD dwTimeout)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
OPERATOR_REQUEST *opReq;
|
|
|
|
EnterCriticalSection(&thisSession->lock);
|
|
|
|
opReq = FindOperatorRequest(thisSession, lpRequestId);
|
|
if (opReq){
|
|
|
|
if ((opReq->state == NTMS_OPSTATE_COMPLETE) ||
|
|
(opReq->state == NTMS_OPSTATE_REFUSED)){
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
opReq->numWaitingThreads++;
|
|
|
|
/*
|
|
* Drop the lock and wait for the op request to complete.
|
|
* No race here: the opReq won't get deleted while
|
|
* numWaitingThreads > 0.
|
|
*/
|
|
LeaveCriticalSection(&thisSession->lock);
|
|
WaitForSingleObject(opReq->completedEvent, dwTimeout);
|
|
EnterCriticalSection(&thisSession->lock);
|
|
|
|
result = (opReq->state == NTMS_OPSTATE_COMPLETE) ? ERROR_SUCCESS :
|
|
(opReq->state == NTMS_OPSTATE_REFUSED) ? ERROR_CANCELLED :
|
|
ERROR_TIMEOUT;
|
|
|
|
ASSERT(opReq->numWaitingThreads > 0);
|
|
opReq->numWaitingThreads--;
|
|
}
|
|
|
|
}
|
|
else {
|
|
result = ERROR_OBJECT_NOT_FOUND;
|
|
}
|
|
|
|
LeaveCriticalSection(&thisSession->lock);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CancelNtmsOperatorRequest(HANDLE hSession, LPNTMS_GUID lpRequestId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
result = CompleteOperatorRequest(thisSession, lpRequestId, NTMS_OPSTATE_REFUSED);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SatisfyNtmsOperatorRequest(HANDLE hSession, LPNTMS_GUID lpRequestId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
result = CompleteOperatorRequest(thisSession, lpRequestId, NTMS_OPSTATE_COMPLETE);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI ImportNtmsDatabase(HANDLE hSession)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI ExportNtmsDatabase(HANDLE hSession)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// BUGBUG - this API not documented and I don't understand it
|
|
HRESULT WINAPI GetNtmsMountDrives( HANDLE hSession,
|
|
LPNTMS_MOUNT_INFORMATION lpMountInfo,
|
|
LPNTMS_GUID lpDriveId,
|
|
DWORD dwCount)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
if (lpMountInfo && lpMountInfo->lpReserved && lpDriveId && dwCount){
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI AllocateNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaPoolId,
|
|
LPNTMS_GUID lpPartitionId, // optional
|
|
LPNTMS_GUID lpMediaId, // in/out
|
|
DWORD dwOptions,
|
|
DWORD dwTimeout,
|
|
LPNTMS_ALLOCATION_INFORMATION lpAllocateInfo)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_POOL *mediaPool;
|
|
|
|
mediaPool = FindMediaPool(lpMediaPoolId);
|
|
if (mediaPool){
|
|
PHYSICAL_MEDIA *physMedia;
|
|
|
|
if (dwOptions & NTMS_ALLOCATE_NEW){
|
|
/*
|
|
* Allocate the first partition (side) of the specified media
|
|
* with a reservation on all other partitions.
|
|
*/
|
|
if (lpPartitionId){
|
|
physMedia = FindPhysicalMedia(lpMediaId);
|
|
if (physMedia){
|
|
result = AllocatePhysicalMediaExclusive(thisSession, physMedia, lpPartitionId, dwTimeout);
|
|
DerefObject(physMedia);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
ASSERT(lpPartitionId);
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else if (dwOptions & NTMS_ALLOCATE_NEXT){
|
|
/*
|
|
* The specified media is (ostensibly) owned by the caller.
|
|
* Allocate the next available partition for him.
|
|
*/
|
|
physMedia = FindPhysicalMedia(lpMediaId);
|
|
if (physMedia){
|
|
MEDIA_PARTITION *nextMediaPartition;
|
|
ASSERT(!lpPartitionId);
|
|
result = AllocateNextPartitionOnExclusiveMedia(thisSession, physMedia, &nextMediaPartition);
|
|
if (result == ERROR_SUCCESS){
|
|
*lpMediaId = nextMediaPartition->logicalMediaGuid;
|
|
}
|
|
DerefObject(physMedia);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
// BUGBUG - are we reserving a physMedia or just
|
|
// a partition here ?
|
|
|
|
BOOL opReqIfNeeded = (dwOptions & NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE) ? FALSE : TRUE;
|
|
result = AllocateMediaFromPool(thisSession, mediaPool, dwTimeout, &physMedia, opReqIfNeeded);
|
|
if (result == ERROR_SUCCESS){
|
|
// BUGBUG - return logicalMediaId ??
|
|
*lpMediaId = physMedia->objHeader.guid;
|
|
}
|
|
}
|
|
|
|
DerefObject(mediaPool);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA_POOL;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeallocateNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpLogicalMediaId,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_PARTITION *thisMediaPartition;
|
|
|
|
thisMediaPartition = FindMediaPartition(lpLogicalMediaId);
|
|
if (thisMediaPartition){
|
|
result = ReleaseMediaPartition(thisSession, thisMediaPartition);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SwapNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaId1,
|
|
LPNTMS_GUID lpMediaId2)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DecommissionNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaPartId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_PARTITION *mediaPart;
|
|
|
|
mediaPart = FindMediaPartition(lpMediaPartId);
|
|
if (mediaPart){
|
|
result = SetMediaPartitionState( mediaPart,
|
|
MEDIAPARTITIONSTATE_DECOMMISSIONED);
|
|
DerefObject(mediaPart);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
DWORD WINAPI SetNtmsMediaComplete( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaPartId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_PARTITION *mediaPart;
|
|
|
|
mediaPart = FindMediaPartition(lpMediaPartId);
|
|
if (mediaPart){
|
|
result = SetMediaPartitionComplete(mediaPart);
|
|
DerefObject(mediaPart);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeleteNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpPhysMediaId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
PHYSICAL_MEDIA *physMedia;
|
|
|
|
physMedia = FindPhysicalMedia(lpPhysMediaId);
|
|
if (physMedia){
|
|
result = DeletePhysicalMedia(physMedia);
|
|
DerefObject(physMedia);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CreateNtmsMediaPoolW( HANDLE hSession,
|
|
LPCWSTR lpPoolName,
|
|
LPNTMS_GUID lpMediaType,
|
|
DWORD dwAction,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
OUT LPNTMS_GUID lpPoolId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_POOL *mediaPool;
|
|
|
|
mediaPool = FindMediaPoolByName((PWSTR)lpPoolName);
|
|
|
|
if (dwAction == NTMS_OPEN_EXISTING){
|
|
if (mediaPool){
|
|
*lpPoolId = mediaPool->objHeader.guid;
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_OBJECT_NOT_FOUND;
|
|
}
|
|
}
|
|
else if (dwAction == NTMS_OPEN_ALWAYS){
|
|
if (mediaPool){
|
|
*lpPoolId = mediaPool->objHeader.guid;
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
mediaPool = NewMediaPool(lpPoolName, lpMediaType, lpSecurityAttributes);
|
|
if (mediaPool){
|
|
// BUGBUG FINISH
|
|
*lpPoolId = mediaPool->objHeader.guid;
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_DATABASE_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
else if (dwAction == NTMS_CREATE_NEW){
|
|
/*
|
|
* Caller is trying to open a new media pool.
|
|
* So if one by that name already exists, fail.
|
|
*/
|
|
if (mediaPool){
|
|
DerefObject(mediaPool);
|
|
result = ERROR_ALREADY_EXISTS;
|
|
}
|
|
else {
|
|
mediaPool = NewMediaPool(lpPoolName, lpMediaType, lpSecurityAttributes);
|
|
if (mediaPool){
|
|
// BUGBUG FINISH
|
|
*lpPoolId = mediaPool->objHeader.guid;
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_DATABASE_FAILURE;
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CreateNtmsMediaPoolA( HANDLE hSession,
|
|
LPCSTR lpPoolName,
|
|
LPNTMS_GUID lpMediaType,
|
|
DWORD dwAction,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
OUT LPNTMS_GUID lpPoolId)
|
|
{
|
|
HRESULT result;
|
|
WCHAR wPoolName[NTMS_OBJECTNAME_LENGTH];
|
|
|
|
AsciiToWChar(wPoolName, lpPoolName, NTMS_OBJECTNAME_LENGTH);
|
|
|
|
result = CreateNtmsMediaPoolW( hSession,
|
|
wPoolName,
|
|
lpMediaType,
|
|
dwAction,
|
|
lpSecurityAttributes,
|
|
lpPoolId);
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsMediaPoolNameW( HANDLE hSession,
|
|
LPNTMS_GUID lpPoolId,
|
|
LPWSTR lpBufName,
|
|
LPDWORD lpdwNameSize)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_POOL *mediaPool;
|
|
|
|
mediaPool = FindMediaPool(lpPoolId);
|
|
if (mediaPool){
|
|
ULONG numChars;
|
|
|
|
EnterCriticalSection(&mediaPool->lock);
|
|
|
|
numChars = wcslen(mediaPool->name)+1;
|
|
ASSERT(numChars < NTMS_OBJECTNAME_LENGTH);
|
|
|
|
if (*lpdwNameSize >= numChars){
|
|
numChars = WStrNCpy(lpBufName, mediaPool->name, *lpdwNameSize);
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*lpdwNameSize = numChars;
|
|
|
|
LeaveCriticalSection(&mediaPool->lock);
|
|
|
|
DerefObject(mediaPool);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsMediaPoolNameA( HANDLE hSession,
|
|
LPNTMS_GUID lpPoolId,
|
|
LPSTR lpBufName,
|
|
LPDWORD lpdwNameSize)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (*lpdwNameSize > NTMS_OBJECTNAME_LENGTH){
|
|
ASSERT(*lpdwNameSize <= NTMS_OBJECTNAME_LENGTH);
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
else {
|
|
WCHAR wBufName[NTMS_OBJECTNAME_LENGTH];
|
|
|
|
result = GetNtmsMediaPoolNameW(hSession, lpPoolId, wBufName, lpdwNameSize);
|
|
if (result == ERROR_SUCCESS){
|
|
WCharToAscii(lpBufName, wBufName, *lpdwNameSize);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI MoveToNtmsMediaPool( HANDLE hSession,
|
|
LPNTMS_GUID lpPhysMediaId,
|
|
LPNTMS_GUID lpPoolId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
PHYSICAL_MEDIA *physMedia;
|
|
|
|
physMedia = FindPhysicalMedia(lpPhysMediaId);
|
|
if (physMedia){
|
|
MEDIA_POOL *destMediaPool;
|
|
|
|
destMediaPool = FindMediaPool(lpPoolId);
|
|
if (destMediaPool){
|
|
|
|
result = MovePhysicalMediaToPool(destMediaPool, physMedia, FALSE);
|
|
|
|
DerefObject(destMediaPool);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
DerefObject(physMedia);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeleteNtmsMediaPool(HANDLE hSession, LPNTMS_GUID lpPoolId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_POOL *mediaPool;
|
|
|
|
mediaPool = FindMediaPool(lpPoolId);
|
|
if (mediaPool){
|
|
result = DeleteMediaPool(mediaPool);
|
|
DerefObject(mediaPool);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA_POOL;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI AddNtmsMediaType( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaTypeId,
|
|
LPNTMS_GUID lpLibId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibId);
|
|
if (lib){
|
|
MEDIA_TYPE_OBJECT *mediaTypeObj;
|
|
|
|
mediaTypeObj = FindMediaTypeObject(lpMediaTypeId);
|
|
if (mediaTypeObj){
|
|
/*
|
|
* The media type is already defined. Succeed.
|
|
*/
|
|
DerefObject(mediaTypeObj);
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
mediaTypeObj = NewMediaTypeObject(lib);
|
|
if (mediaTypeObj){
|
|
|
|
// BUGBUG FINISH - create new standard media pools
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeleteNtmsMediaType( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaTypeId,
|
|
LPNTMS_GUID lpLibId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibId);
|
|
if (lib){
|
|
MEDIA_TYPE_OBJECT *mediaTypeObj;
|
|
|
|
mediaTypeObj = FindMediaTypeObject(lpMediaTypeId);
|
|
if (mediaTypeObj){
|
|
result = DeleteMediaTypeObject(mediaTypeObj);
|
|
DerefObject(mediaTypeObj);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/*
|
|
* ChangeNtmsMediaType
|
|
*
|
|
* Move the media to the media pool and change the media's
|
|
* type to the pool's media type.
|
|
*/
|
|
DWORD WINAPI ChangeNtmsMediaType( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaId,
|
|
LPNTMS_GUID lpPoolId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
PHYSICAL_MEDIA *physMedia;
|
|
|
|
physMedia = FindPhysicalMedia(lpMediaId);
|
|
if (physMedia){
|
|
MEDIA_POOL *destMediaPool;
|
|
|
|
destMediaPool = FindMediaPool(lpPoolId);
|
|
if (destMediaPool){
|
|
|
|
result = MovePhysicalMediaToPool(destMediaPool, physMedia, TRUE);
|
|
|
|
DerefObject(destMediaPool);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
DerefObject(physMedia);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI MountNtmsMedia(HANDLE hSession,
|
|
LPNTMS_GUID lpMediaOrPartitionIds,
|
|
IN OUT LPNTMS_GUID lpDriveIds,
|
|
DWORD dwCount,
|
|
DWORD dwOptions,
|
|
int dwPriority,
|
|
DWORD dwTimeout,
|
|
LPNTMS_MOUNT_INFORMATION lpMountInfo)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
/*
|
|
* Validate that we can safely read the media and drive GUIDs
|
|
* that were passed in by the caller (this just verifies that the
|
|
* buffers are readable; it doesn't verify the GUIDs themselves).
|
|
*/
|
|
if (ValidateBuffer(lpMediaOrPartitionIds, dwCount*sizeof(NTMS_GUID))){
|
|
if (ValidateBuffer(lpDriveIds, dwCount*sizeof(NTMS_GUID))){
|
|
WORKGROUP *workGroup;
|
|
|
|
/*
|
|
* Create a work group, which is a group of workItems,
|
|
* to service each component of the mount.
|
|
*/
|
|
workGroup = NewWorkGroup();
|
|
if (workGroup){
|
|
result = BuildMountWorkGroup( workGroup,
|
|
lpMediaOrPartitionIds,
|
|
lpDriveIds,
|
|
dwCount,
|
|
dwOptions,
|
|
dwPriority);
|
|
if (result == ERROR_SUCCESS){
|
|
|
|
/*
|
|
* Give the mount workItems to the library thread.
|
|
*/
|
|
result = ScheduleWorkGroup(workGroup);
|
|
if (result == ERROR_SUCCESS){
|
|
DWORD waitRes;
|
|
|
|
/*
|
|
* Wait for all the mounts to complete.
|
|
*/
|
|
waitRes = WaitForSingleObject(workGroup->allWorkItemsCompleteEvent, dwTimeout);
|
|
if (waitRes == WAIT_TIMEOUT){
|
|
result = ERROR_TIMEOUT;
|
|
}
|
|
else {
|
|
result = workGroup->resultStatus;
|
|
}
|
|
}
|
|
|
|
FreeWorkGroup(workGroup);
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_DRIVE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DismountNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpMediaOrPartitionIds,
|
|
DWORD dwCount,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
if (ValidateBuffer(lpMediaOrPartitionIds, dwCount*sizeof(NTMS_GUID))){
|
|
WORKGROUP *workGroup;
|
|
|
|
/*
|
|
* Create a work group, which is a group of workItems,
|
|
* to service each component of the mount.
|
|
*/
|
|
workGroup = NewWorkGroup();
|
|
if (workGroup){
|
|
result = BuildDismountWorkGroup( workGroup,
|
|
lpMediaOrPartitionIds,
|
|
dwCount,
|
|
dwOptions);
|
|
if (result == ERROR_SUCCESS){
|
|
|
|
/*
|
|
* Give the mount workItems to the library thread.
|
|
*/
|
|
result = ScheduleWorkGroup(workGroup);
|
|
if (result == ERROR_SUCCESS){
|
|
/*
|
|
* Wait for all the mounts to complete.
|
|
*/
|
|
WaitForSingleObject(workGroup->allWorkItemsCompleteEvent, INFINITE);
|
|
|
|
result = workGroup->resultStatus;
|
|
}
|
|
|
|
FreeWorkGroup(workGroup);
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI EjectNtmsMedia(HANDLE hSession,
|
|
LPNTMS_GUID lpMediaId,
|
|
LPNTMS_GUID lpEjectOperation,
|
|
DWORD dwAction)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
PHYSICAL_MEDIA *physMedia;
|
|
|
|
physMedia = FindPhysicalMedia(lpMediaId);
|
|
if (physMedia){
|
|
MEDIA_POOL *mediaPool;
|
|
LIBRARY *lib;
|
|
|
|
/*
|
|
* Get the library for this media.
|
|
*/
|
|
LockPhysicalMediaWithLibrary(physMedia);
|
|
mediaPool = physMedia->owningMediaPool;
|
|
lib = mediaPool ? mediaPool->owningLibrary : NULL;
|
|
if (lib){
|
|
RefObject(lib);
|
|
}
|
|
UnlockPhysicalMediaWithLibrary(physMedia);
|
|
|
|
if (lib){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem for the eject.
|
|
*/
|
|
BuildEjectWorkItem(workItem, physMedia, lpEjectOperation, dwAction);
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
* Then wait for the workItem to complete.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
* Also get result parameters (eject guid is returned
|
|
* when dwAction = NTMS_EJECT_START).
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
*lpEjectOperation = workItem->currentOp.guidArg;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_DATABASE_FAILURE;
|
|
}
|
|
|
|
DerefObject(physMedia);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
DWORD WINAPI InjectNtmsMedia( HANDLE hSession,
|
|
LPNTMS_GUID lpLibraryId,
|
|
LPNTMS_GUID lpInjectOperation,
|
|
DWORD dwAction)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
if (lib->state == LIBSTATE_ONLINE){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem for the inject.
|
|
*/
|
|
BuildInjectWorkItem(workItem, lpInjectOperation, dwAction);
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
* Then wait for the workItem to complete.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
*lpInjectOperation = workItem->currentOp.guidArg;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_LIBRARY_OFFLINE;
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI AccessNtmsLibraryDoor( HANDLE hSession,
|
|
LPNTMS_GUID lpLibraryId,
|
|
DWORD dwAction)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
if (lib->state == LIBSTATE_ONLINE){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem for the door unlock.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_DOORACCESS;
|
|
workItem->currentOp.options = dwAction;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
* Note: If the library is busy, the workItem will be completed
|
|
* immediately and the door will be unlocked later.
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_LIBRARY_OFFLINE;
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CleanNtmsDrive(HANDLE hSession, LPNTMS_GUID lpDriveId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
DRIVE *drive;
|
|
|
|
drive = FindDrive(lpDriveId);
|
|
if (drive){
|
|
WORKITEM *workItem;
|
|
|
|
ASSERT(drive->lib);
|
|
|
|
workItem = DequeueFreeWorkItem(drive->lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem to clean the drive.
|
|
* Reference every object pointed to by the workItem.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_CLEANDRIVE;
|
|
workItem->currentOp.drive = drive;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
RefObject(drive);
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DerefObject(drive);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_DRIVE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DismountNtmsDrive(HANDLE hSession, LPNTMS_GUID lpDriveId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
DRIVE *drive;
|
|
|
|
drive = FindDrive(lpDriveId);
|
|
if (drive){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(drive->lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem to dismount.
|
|
* Reference every object pointed to by the workItem.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_DISMOUNT;
|
|
workItem->currentOp.drive = drive;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
RefObject(drive);
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DerefObject(drive);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_DRIVE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI InventoryNtmsLibrary( HANDLE hSession,
|
|
LPNTMS_GUID lpLibraryId,
|
|
DWORD dwAction)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
if (lib->state == LIBSTATE_ONLINE){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem for the inventory.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_INVENTORY;
|
|
workItem->currentOp.options = dwAction;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
* Note: If the library is busy, the workItem will be completed
|
|
* immediately and the inventory will happen later.
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_LIBRARY_OFFLINE;
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI UpdateNtmsOmidInfo( HANDLE hSession,
|
|
LPNTMS_GUID lpLogicalMediaId,
|
|
DWORD labelType,
|
|
DWORD numberOfBytes,
|
|
LPVOID lpBuffer)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
MEDIA_PARTITION *mediaPart;
|
|
|
|
mediaPart = FindMediaPartition(lpLogicalMediaId);
|
|
if (mediaPart){
|
|
MEDIA_POOL *mediaPool;
|
|
LIBRARY *lib;
|
|
|
|
ASSERT(mediaPart->owningPhysicalMedia);
|
|
|
|
/*
|
|
* Get the library for this media.
|
|
*/
|
|
LockPhysicalMediaWithLibrary(mediaPart->owningPhysicalMedia);
|
|
mediaPool = mediaPart->owningPhysicalMedia->owningMediaPool;
|
|
lib = mediaPool ? mediaPool->owningLibrary : NULL;
|
|
if (lib){
|
|
RefObject(lib);
|
|
}
|
|
UnlockPhysicalMediaWithLibrary(mediaPart->owningPhysicalMedia);
|
|
|
|
if (lib){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_UPDATEOMID;
|
|
workItem->currentOp.options = labelType;
|
|
workItem->currentOp.buf = lpBuffer;
|
|
workItem->currentOp.bufLen = numberOfBytes;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_DATABASE_FAILURE;
|
|
}
|
|
|
|
DerefObject(mediaPart);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_MEDIA;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CancelNtmsLibraryRequest(HANDLE hSession, LPNTMS_GUID lpRequestId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
WORKITEM *workItem = NULL;
|
|
LIST_ENTRY *listEntry;
|
|
|
|
/*
|
|
* Go through every library and find the workItem to cancel.
|
|
* This is HUGELY INEFFICIENT but this is a rare call.
|
|
* This is better than putting every request into the database.
|
|
*
|
|
* BUGBUG - this only cancels workItems that are still pending.
|
|
* what about workItems currently being processed ?
|
|
*/
|
|
EnterCriticalSection(&g_globalServiceLock);
|
|
listEntry = &g_allLibrariesList;
|
|
while ((listEntry = listEntry->Flink) != &g_allLibrariesList){
|
|
LIBRARY *lib = CONTAINING_RECORD(listEntry, LIBRARY, allLibrariesListEntry);
|
|
workItem = DequeuePendingWorkItemByGuid(lib, lpRequestId);
|
|
if (workItem){
|
|
break;
|
|
}
|
|
}
|
|
LeaveCriticalSection(&g_globalServiceLock);
|
|
|
|
if (workItem){
|
|
/*
|
|
* Found the workItem to cancel.
|
|
* Dereference any objects pointed to by the workItem
|
|
* and put it back in the free list.
|
|
*/
|
|
FlushWorkItem(workItem);
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_OBJECT_NOT_FOUND;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI ReserveNtmsCleanerSlot( HANDLE hSession,
|
|
LPNTMS_GUID lpLibraryId,
|
|
LPNTMS_GUID lpSlotId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
SLOT *slot;
|
|
|
|
slot = FindLibrarySlot(lib, lpSlotId);
|
|
if (slot){
|
|
/*
|
|
* To be reserved as the cleaner slot, the slot must
|
|
* be empty and the library must have no cleaner slot reserved.
|
|
* Redundant calls to reserve the same cleaner slot fail.
|
|
*/
|
|
EnterCriticalSection(&lib->lock);
|
|
if (lib->cleanerSlotIndex == NO_SLOT_INDEX){
|
|
ASSERT(!slot->isCleanerSlot);
|
|
if (slot->insertedMedia){
|
|
result = ERROR_RESOURCE_NOT_AVAILABLE; // BUGBUG ERROR_SLOT_FULL; not defined
|
|
}
|
|
else {
|
|
lib->cleanerSlotIndex = slot->slotIndex;
|
|
slot->isCleanerSlot = TRUE;
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_CLEANER_SLOT_SET;
|
|
}
|
|
LeaveCriticalSection(&lib->lock);
|
|
|
|
DerefObject(slot);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE; // BUGBUG ERROR_INVALID_SLOT not defined
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI ReleaseNtmsCleanerSlot(HANDLE hSession, LPNTMS_GUID lpLibraryId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
if (lib->cleanerSlotIndex == NO_SLOT_INDEX){
|
|
/*
|
|
* There is no cleaner slot configured.
|
|
*/
|
|
result = ERROR_CLEANER_SLOT_NOT_SET;
|
|
}
|
|
else {
|
|
SLOT *slot;
|
|
|
|
ASSERT(lib->cleanerSlotIndex < lib->numSlots);
|
|
slot = &lib->slots[lib->cleanerSlotIndex];
|
|
ASSERT(slot->isCleanerSlot);
|
|
|
|
if (slot->insertedMedia){
|
|
result = ERROR_RESOURCE_NOT_AVAILABLE; // BUGBUG ERROR_SLOT_FULL; not defined
|
|
}
|
|
else {
|
|
slot->isCleanerSlot = FALSE;
|
|
lib->cleanerSlotIndex = NO_SLOT_INDEX;
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI InjectNtmsCleaner( HANDLE hSession,
|
|
LPNTMS_GUID lpLibraryId,
|
|
LPNTMS_GUID lpInjectOperation,
|
|
DWORD dwNumberOfCleansLeft,
|
|
DWORD dwAction)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
|
|
EnterCriticalSection(&lib->lock);
|
|
|
|
/*
|
|
* The library must have a designated cleaner slot index reserved
|
|
* in order to receive the cleaner.
|
|
*
|
|
* BUGBUG - move all these checks to the lib thread.
|
|
*/
|
|
if (lib->cleanerSlotIndex == NO_SLOT_INDEX){
|
|
result = ERROR_CLEANER_SLOT_NOT_SET;
|
|
}
|
|
else {
|
|
SLOT *slot = &lib->slots[lib->cleanerSlotIndex];
|
|
ASSERT(lib->cleanerSlotIndex < lib->numSlots);
|
|
ASSERT(slot->isCleanerSlot);
|
|
if (slot->insertedMedia){
|
|
result = ERROR_RESOURCE_NOT_AVAILABLE; // BUGBUG ERROR_SLOT_FULL; not defined
|
|
}
|
|
else {
|
|
|
|
if (dwAction == NTMS_INJECT_START){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_INJECTCLEANER;
|
|
workItem->currentOp.lParam = dwNumberOfCleansLeft;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* When we enqueued the workItem in the pending queue,
|
|
* it got assigned a requestGuid. Since we're holding the
|
|
* library lock, that workItem hasn't gone anywhere yet.
|
|
* So its ok to read out the requestGuid from the workItem.
|
|
*/
|
|
*lpInjectOperation = workItem->currentOp.requestGuid;
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
* Note: The workItem will complete as soon as the library thread
|
|
* starts the injection. The app may cancel the cleaner
|
|
* injection using NTMS_INJECT_STOP and the returned GUID.
|
|
* BUGBUG ?
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else if (dwAction == NTMS_INJECT_STOP){
|
|
result = StopCleanerInjection(lib, lpInjectOperation);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&lib->lock);
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI EjectNtmsCleaner( HANDLE hSession,
|
|
LPNTMS_GUID lpLibraryId,
|
|
LPNTMS_GUID lpEjectOperation,
|
|
DWORD dwAction)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
|
|
EnterCriticalSection(&lib->lock);
|
|
|
|
if (dwAction == NTMS_EJECT_START){
|
|
WORKITEM *workItem;
|
|
|
|
workItem = DequeueFreeWorkItem(lib, TRUE);
|
|
if (workItem){
|
|
/*
|
|
* Build the workItem.
|
|
*/
|
|
RtlZeroMemory(&workItem->currentOp, sizeof(workItem->currentOp));
|
|
workItem->currentOp.opcode = NTMS_LM_EJECTCLEANER;
|
|
workItem->currentOp.resultStatus = ERROR_IO_PENDING;
|
|
|
|
/*
|
|
* Give this workItem to the library and wake up the library thread.
|
|
*/
|
|
EnqueuePendingWorkItem(workItem->owningLib, workItem);
|
|
|
|
/*
|
|
* When we enqueued the workItem in the pending queue,
|
|
* it got assigned a requestGuid. Since we're holding the
|
|
* library lock, that workItem hasn't gone anywhere yet.
|
|
* So its ok to read out the requestGuid from the workItem.
|
|
*/
|
|
*lpEjectOperation = workItem->currentOp.requestGuid;
|
|
|
|
/*
|
|
* Wait for the request to be processed by the library thread.
|
|
* Note: The workItem will complete as soon as the library thread
|
|
* starts the ejection. The app may cancel the cleaner
|
|
* ejection using NTMS_EJECT_STOP and the returned GUID.
|
|
* BUGBUG ?
|
|
*/
|
|
WaitForSingleObject(workItem->workItemCompleteEvent, INFINITE);
|
|
|
|
/*
|
|
* Get result from the completed workItem.
|
|
*/
|
|
result = workItem->currentOp.resultStatus;
|
|
|
|
EnqueueFreeWorkItem(workItem->owningLib, workItem);
|
|
}
|
|
else {
|
|
result = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else if (dwAction == NTMS_EJECT_STOP){
|
|
result = StopCleanerEjection(lib, lpEjectOperation);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
LeaveCriticalSection(&lib->lock);
|
|
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeleteNtmsLibrary(HANDLE hSession, LPNTMS_GUID lpLibraryId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
LIBRARY *lib;
|
|
|
|
lib = FindLibrary(lpLibraryId);
|
|
if (lib){
|
|
|
|
result = DeleteLibrary(lib);
|
|
|
|
/*
|
|
* Dereference the library due to the reference that happened
|
|
* when we called FindLibrary. The library will get deleted
|
|
* once all references go away.
|
|
*/
|
|
DerefObject(lib);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_LIBRARY;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeleteNtmsDrive(HANDLE hSession, LPNTMS_GUID lpDriveId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
DRIVE *drive;
|
|
|
|
drive = FindDrive(lpDriveId);
|
|
if (drive){
|
|
|
|
result = DeleteDrive(drive);
|
|
|
|
/*
|
|
* Dereference the drive due to the reference that happened
|
|
* when we called FindDrive. The drive will get deleted
|
|
* once all references go away.
|
|
*/
|
|
DerefObject(drive);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_DRIVE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsRequestOrder( HANDLE hSession,
|
|
LPNTMS_GUID lpRequestId,
|
|
LPDWORD lpdwOrderNumber)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
if (lpRequestId){
|
|
LIST_ENTRY *listEntry;
|
|
|
|
result = ERROR_INVALID_HANDLE;
|
|
*lpdwOrderNumber = 0;
|
|
|
|
EnterCriticalSection(&g_globalServiceLock);
|
|
|
|
/*
|
|
* Go through every library and find the pending workItem.
|
|
* This is HUGELY INEFFICIENT but this is a rare call.
|
|
* This is better than putting every request into the database.
|
|
*/
|
|
listEntry = &g_allLibrariesList;
|
|
while ((listEntry = listEntry->Flink) != &g_allLibrariesList){
|
|
LIBRARY *lib = CONTAINING_RECORD(listEntry, LIBRARY, allLibrariesListEntry);
|
|
LIST_ENTRY *listEntry2;
|
|
ULONG requestOrder = 1;
|
|
|
|
EnterCriticalSection(&lib->lock);
|
|
|
|
listEntry2 = &lib->pendingWorkItemsList;
|
|
while ((listEntry2 = listEntry2->Flink) != &lib->pendingWorkItemsList){
|
|
WORKITEM *workItem = CONTAINING_RECORD(listEntry2, WORKITEM, libListEntry);
|
|
if (RtlEqualMemory(&workItem->currentOp.requestGuid, lpRequestId, sizeof(NTMS_GUID))){
|
|
*lpdwOrderNumber = requestOrder;
|
|
result = ERROR_SUCCESS;
|
|
break;
|
|
}
|
|
else {
|
|
requestOrder++;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&lib->lock);
|
|
|
|
if (result == ERROR_SUCCESS){
|
|
break;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&g_globalServiceLock);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsRequestOrder( HANDLE hSession,
|
|
LPNTMS_GUID lpRequestId,
|
|
DWORD dwOrderNumber)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DeleteNtmsRequests(HANDLE hSession,
|
|
LPNTMS_GUID lpRequestId,
|
|
DWORD dwType,
|
|
DWORD dwCount)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI BeginNtmsDeviceChangeDetection(HANDLE hSession, LPHANDLE lpDetectHandle)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsDeviceChangeDetection( HANDLE hSession,
|
|
HANDLE DetectHandle,
|
|
LPNTMS_GUID lpRequestId,
|
|
DWORD dwType,
|
|
DWORD dwCount)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI EndNtmsDeviceChangeDetection(HANDLE hSession, HANDLE DetectHandle)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******** BUGBUG: INtmsObjectManagement1 APIs *********************/
|
|
|
|
DWORD WINAPI GetNtmsObjectSecurity( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
SECURITY_INFORMATION RequestedInformation,
|
|
PSECURITY_DESCRIPTOR lpSecurityDescriptor,
|
|
DWORD nLength,
|
|
LPDWORD lpnLengthNeeded)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsObjectSecurity( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
SECURITY_INFORMATION SecurityInformation,
|
|
PSECURITY_DESCRIPTOR lpSecurityDescriptor)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsObjectAttributeW( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
LPCWSTR lpAttributeName,
|
|
LPVOID lpAttributeData,
|
|
LPDWORD lpAttributeSize)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsObjectAttributeA( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
LPCSTR lpAttributeName,
|
|
LPVOID lpAttributeData,
|
|
LPDWORD lpAttributeSize)
|
|
{
|
|
HRESULT result;
|
|
WCHAR wAttributeName[NTMS_OBJECTNAME_LENGTH];
|
|
|
|
AsciiToWChar(wAttributeName, lpAttributeName, NTMS_OBJECTNAME_LENGTH);
|
|
result = GetNtmsObjectAttributeW( hSession,
|
|
lpObjectId,
|
|
dwType,
|
|
wAttributeName,
|
|
lpAttributeData,
|
|
lpAttributeSize);
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsObjectAttributeA( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
LPCSTR lpAttributeName,
|
|
LPVOID lpAttributeData,
|
|
DWORD dwAttributeSize)
|
|
{
|
|
HRESULT result;
|
|
WCHAR wAttributeName[NTMS_OBJECTNAME_LENGTH];
|
|
|
|
AsciiToWChar(wAttributeName, lpAttributeName, NTMS_OBJECTNAME_LENGTH);
|
|
result = SetNtmsObjectAttributeW( hSession,
|
|
lpObjectId,
|
|
dwType,
|
|
wAttributeName,
|
|
lpAttributeData,
|
|
dwAttributeSize);
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsObjectAttributeW( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
LPCWSTR lpAttributeName,
|
|
LPVOID lpAttributeData,
|
|
DWORD AttributeSize)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI EnumerateNtmsObject( HANDLE hSession,
|
|
const LPNTMS_GUID lpContainerId,
|
|
LPNTMS_GUID lpList,
|
|
LPDWORD lpdwListSize,
|
|
DWORD dwType,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI EnableNtmsObject(HANDLE hSession, DWORD dwType, LPNTMS_GUID lpObjectId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DisableNtmsObject(HANDLE hSession, DWORD dwType, LPNTMS_GUID lpObjectId)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
/******* BUGBUG: INtmsObjectInfo1 APIs ****************************/
|
|
|
|
// BUGBUG - these 4 functions have another form with type,size as last args
|
|
|
|
|
|
HRESULT WINAPI GetNtmsServerObjectInformationW( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONW lpInfo,
|
|
int revision)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
HRESULT WINAPI GetNtmsServerObjectInformationA( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONA lpInfo,
|
|
int revision)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (lpInfo){
|
|
NTMS_OBJECTINFORMATIONW wObjInfo;
|
|
|
|
ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
|
|
result = GetNtmsServerObjectInformationW(hSession, lpObjectId, &wObjInfo, revision);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
HRESULT WINAPI SetNtmsServerObjectInformationW( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONW lpInfo,
|
|
int revision)\
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
HRESULT WINAPI SetNtmsServerObjectInformationA( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONA lpInfo,
|
|
int revision)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (lpObjectId && lpInfo){
|
|
NTMS_OBJECTINFORMATIONW wObjInfo;
|
|
|
|
ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
|
|
result = SetNtmsServerObjectInformationW(hSession, lpObjectId, &wObjInfo, revision);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CreateNtmsMediaA( HANDLE hSession,
|
|
LPNTMS_OBJECTINFORMATIONA lpMedia,
|
|
LPNTMS_OBJECTINFORMATIONA lpList,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (lpMedia && lpList){
|
|
NTMS_OBJECTINFORMATIONW wObjInfoMedia, wObjInfoList;
|
|
|
|
ConvertObjectInfoAToWChar(&wObjInfoMedia, lpMedia);
|
|
ConvertObjectInfoAToWChar(&wObjInfoList, lpList);
|
|
result = CreateNtmsMediaW(hSession, &wObjInfoMedia, &wObjInfoList, dwOptions);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CreateNtmsMediaW( HANDLE hSession,
|
|
LPNTMS_OBJECTINFORMATIONW lpMedia,
|
|
LPNTMS_OBJECTINFORMATIONW lpList,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
DWORD WINAPI GetNtmsObjectInformationA( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONA lpInfo)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (lpInfo){
|
|
NTMS_OBJECTINFORMATIONW wObjInfo;
|
|
|
|
ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
|
|
result = GetNtmsObjectInformationW(hSession, lpObjectId, &wObjInfo);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsObjectInformationW( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONW lpInfo)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
if (lpObjectId && lpInfo){
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsObjectInformationA( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONA lpInfo)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (lpInfo){
|
|
NTMS_OBJECTINFORMATIONW wObjInfo;
|
|
|
|
ConvertObjectInfoAToWChar(&wObjInfo, lpInfo);
|
|
result = SetNtmsObjectInformationW(hSession, lpObjectId, &wObjInfo);
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsObjectInformationW( HANDLE hSession,
|
|
LPNTMS_GUID lpObjectId,
|
|
LPNTMS_OBJECTINFORMATIONW lpInfo)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
if (lpObjectId && lpInfo){
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
HANDLE WINAPI OpenNtmsNotification(HANDLE hSession, DWORD dwType)
|
|
{
|
|
HANDLE hNotify;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
hNotify = NULL;
|
|
}
|
|
else {
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
hNotify = NULL;
|
|
}
|
|
|
|
return hNotify;
|
|
}
|
|
|
|
|
|
DWORD WINAPI WaitForNtmsNotification( HANDLE hNotification,
|
|
LPNTMS_NOTIFICATIONINFORMATION lpNotificationInformation,
|
|
DWORD dwTimeout)
|
|
{
|
|
HRESULT result;
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI CloseNtmsNotification(HANDLE hNotification)
|
|
{
|
|
HRESULT result;
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
DWORD WINAPI EjectDiskFromSADriveA( LPCSTR lpComputerName,
|
|
LPCSTR lpAppName,
|
|
LPCSTR lpDeviceName,
|
|
HWND hWnd,
|
|
LPCSTR lpTitle,
|
|
LPCSTR lpMessage,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI EjectDiskFromSADriveW( LPCWSTR lpComputerName,
|
|
LPCWSTR lpAppName,
|
|
LPCWSTR lpDeviceName,
|
|
HWND hWnd,
|
|
LPCWSTR lpTitle,
|
|
LPCWSTR lpMessage,
|
|
DWORD dwOptions)
|
|
{
|
|
HRESULT result;
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetVolumesFromDriveA( LPSTR pszDriveName,
|
|
LPSTR* VolumeNameBufferPtr,
|
|
LPSTR* DriveLetterBufferPtr)
|
|
{
|
|
HRESULT result;
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetVolumesFromDriveW( LPWSTR pszDriveName,
|
|
LPWSTR *VolumeNameBufferPtr,
|
|
LPWSTR *DriveLetterBufferPtr)
|
|
{
|
|
HRESULT result;
|
|
|
|
// BUGBUG FINISH
|
|
result = ERROR_SUCCESS;
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI IdentifyNtmsSlot(HANDLE hSession, LPNTMS_GUID lpSlotId, DWORD dwOption)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsUIOptionsA( HANDLE hSession,
|
|
const LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
LPSTR lpszDestination,
|
|
LPDWORD lpAttributeSize)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI GetNtmsUIOptionsW( HANDLE hSession,
|
|
const LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
LPWSTR lpszDestination,
|
|
LPDWORD lpdwSize)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsUIOptionsA( HANDLE hSession,
|
|
const LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
DWORD dwOperation,
|
|
LPCSTR lpszDestination)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD WINAPI SetNtmsUIOptionsW( HANDLE hSession,
|
|
const LPNTMS_GUID lpObjectId,
|
|
DWORD dwType,
|
|
DWORD dwOperation,
|
|
LPCWSTR lpszDestination)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (ValidateSessionHandle(hSession)){
|
|
SESSION *thisSession = (SESSION *)hSession;
|
|
|
|
// BUGBUG FINISH
|
|
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
else {
|
|
result = ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
if (result != ERROR_SUCCESS){
|
|
SetLastError(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|