|
|
#include "nwcompat.hxx"
#pragma hdrstop
//----------------------------------------------------------------------------
//
// Function: NWApiGetBinderyHandle
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiGetBinderyHandle( NWCONN_HANDLE *phConnReturned, BSTR bstrBinderyName, CCredentials &Credentials ) { CHAR szBinderyName[OBJ_NAME_SIZE + 1]; NWLOCAL_SCOPE ScopeFlag = 0; NWCONN_HANDLE hConn = NULL; NWCCODE ccode = SUCCESSFUL; HRESULT hr = S_OK;
PNWC_CONTEXT pNWCContext = NULL; LPWSTR pszUserName = NULL, pszPassword = NULL; BOOL fLoggedIn = FALSE;
//
// Try the cache for the passed in credentials.
//
ENTER_BIND_CRITSECT() ; if (pNWCContext = BindCacheLookup(bstrBinderyName, Credentials)) { *phConnReturned = pNWCContext->hConn; LEAVE_BIND_CRITSECT() ; return S_OK; }
//
// Entry not found in the cache, need to allocate a new one.
//
hr = BindCacheAllocEntry(&pNWCContext); if (FAILED(hr)) { LEAVE_BIND_CRITSECT() ; RRETURN(hr); }
UnicodeToAnsiString( bstrBinderyName, szBinderyName, 0 );
hr = Credentials.GetUserName(&pszUserName); BAIL_ON_FAILURE(hr); hr = Credentials.GetPassword(&pszPassword); BAIL_ON_FAILURE(hr);
if (pszUserName) { hr = NWApiCheckUserLoggedInToServer(bstrBinderyName, pszUserName); BAIL_ON_FAILURE(hr);
if (hr == S_FALSE) { // Log in the user
NETRESOURCE netResource; DWORD dwStatus;
netResource.dwType = RESOURCETYPE_ANY; netResource.lpLocalName = NULL; netResource.lpRemoteName = (PWSTR) bstrBinderyName; netResource.lpProvider = NULL; dwStatus = WNetAddConnection2( &netResource, pszPassword ? pszPassword : L"", pszUserName, 0 // don't make a persistent connection
);
hr = HRESULT_FROM_WIN32(dwStatus); BAIL_ON_FAILURE(hr); fLoggedIn = TRUE; } }
ccode = NWCCOpenConnByName( 0, szBinderyName, NWCC_NAME_FORMAT_BIND, NWCC_OPEN_UNLICENSED, NWCC_TRAN_TYPE_WILD, &hConn ); hr = HRESULT_FROM_NWCCODE(ccode); BAIL_ON_FAILURE(hr);
pNWCContext->hConn = hConn;
hr = BindCacheAdd(bstrBinderyName, Credentials, fLoggedIn, pNWCContext) ; BAIL_ON_FAILURE(hr);
*phConnReturned = hConn;
FreeADsStr(pszUserName); FreeADsStr(pszPassword);
LEAVE_BIND_CRITSECT();
RRETURN(hr);
error: *phConnReturned = NULL;
if (hConn) { NWCCCloseConn(hConn); }
if (fLoggedIn) { // log out
WNetCancelConnection2((LPWSTR)szBinderyName, 0, FALSE); }
if (pNWCContext) { BindCacheFreeEntry(pNWCContext); }
FreeADsStr(pszUserName); FreeADsStr(pszPassword);
LEAVE_BIND_CRITSECT(); RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiReleaseBinderyHandle
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiReleaseBinderyHandle( NWCONN_HANDLE hConn ) { HRESULT hr = S_OK; NWCCODE ccode = SUCCESSFUL; PNWC_CONTEXT pNWCContext = NULL; DWORD dwStatus;
// note that if lookup succeeds, it add-refs the context, so we have
// to deref twice below: once for the ref we just added, and once
// for our caller's ref that they're trying to release
pNWCContext = BindCacheLookupByConn(hConn);
if (!pNWCContext) RRETURN(E_FAIL);
if (BindCacheDeref(pNWCContext) && (BindCacheDeref(pNWCContext) == 0)) {
// ref count has dropped to zero and it's gone from cache
ccode = NWCCCloseConn(hConn); hr = HRESULT_FROM_NWCCODE(ccode); BAIL_ON_FAILURE(hr);
if (pNWCContext->fLoggedIn) { // logout
dwStatus = WNetCancelConnection2( pNWCContext->pszBinderyName, 0, FALSE);
hr = HRESULT_FROM_WIN32(dwStatus); BAIL_ON_FAILURE(hr); }
BindCacheFreeEntry(pNWCContext); }
RRETURN(hr);
error: // N.B.: If we're here, we must have bailed from inside of
// the BindCacheDeref block, and so pNWCContext must have
// been removed from the cache. Thus, it's safe to free
// it (and not to do so would cause a leak).
BindCacheFreeEntry(pNWCContext);
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiIsUserLoggedInToServer
//
// Synopsis: Returns S_OK if pszUserName is logged in to bstrBinderyName,
// S_FALSE if she isn't
//
//----------------------------------------------------------------------------
HRESULT NWApiCheckUserLoggedInToServer( BSTR bstrBinderyName, LPWSTR pszUserName ) { DWORD err; HRESULT hr;
WCHAR pszUser[NW_USER_SIZE+1]; DWORD dwUserLength = NW_USER_SIZE+1; err = WNetGetUser(bstrBinderyName, pszUser, &dwUserLength); switch(err) { case NO_ERROR: if (_wcsicmp(pszUser, pszUserName) == 0) hr = S_OK; else hr = S_FALSE;
break;
case ERROR_NOT_CONNECTED: hr = S_FALSE; break;
default: hr = HRESULT_FROM_WIN32(err); }
return hr;
}
//----------------------------------------------------------------------------
//
// Function: NWApiWriteProperty
//
// Synopsis: This function modifies values of a bindery property. For now, it
// only accept one buffer segment. However, one segment is enough
// for most practical purpose. If the bindery property does not
// exist, the function will attempt to create the property.
//
//----------------------------------------------------------------------------
HRESULT NWApiWriteProperty( NWCONN_HANDLE hConn, BSTR bstrObjectName, NWOBJ_TYPE wObjType, LPSTR lpszPropertyName, LPBYTE SegmentData ) { CHAR szObjectName[OBJ_NAME_SIZE + 1]; CHAR szPropertyName[OBJ_NAME_SIZE + 1]; HRESULT hr = S_OK; NWCCODE ccode;
//
// Convert BSTR into an ANSI representation required by NW APIs. "0" is
// passed to UnicodeToAnsiString when the length of the string is unknown.
//
UnicodeToAnsiString( bstrObjectName, szObjectName, 0 );
strcpy(szPropertyName, lpszPropertyName);
ccode = NWWritePropertyValue( hConn, szObjectName, wObjType, szPropertyName, 1, // "1" for one segment.
SegmentData, 0 // "0" for no more segment.
); //
// Create the property if it doesn't exist and attempt to write again.
//
if (ccode == NO_SUCH_PROPERTY) {
hr = NWApiCreateProperty( hConn, bstrObjectName, wObjType, lpszPropertyName, BF_ITEM ); BAIL_ON_FAILURE(hr);
ccode = NWWritePropertyValue( hConn, szObjectName, wObjType, szPropertyName, 1, // "1" for one segment.
SegmentData, 0 // "0" for no more segment.
); }
hr = HRESULT_FROM_NWCCODE(ccode);
error:
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiObjectEnum
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiObjectEnum( NWCONN_HANDLE hConn, NWOBJ_TYPE dwObjType, LPWSTR *lppszObjectName, DWORD *pdwResumeObjectID ) { HRESULT hr = S_OK; LPWSTR lpszTemp = NULL; NWCCODE ccode = SUCCESSFUL; NWOBJ_TYPE pdwObjType = 0xFFFF; NWFLAGS pucHasProperties; NWFLAGS pucObjectFlags; NWFLAGS pucObjSecurity; CHAR szObjectName[OBJ_NAME_SIZE + 1];
nstr8 searchObjectName[48] = "*";
//
// This call will fail and return 0xffff if the user is not authenticated
// on the server to which the hConn handle is attached to.
//
ccode = NWScanObject( hConn, searchObjectName, dwObjType, pdwResumeObjectID, szObjectName, &pdwObjType, &pucHasProperties, &pucObjectFlags, &pucObjSecurity ); hr = HRESULT_FROM_NWCCODE(ccode); BAIL_ON_FAILURE(hr);
lpszTemp = AllocateUnicodeString(szObjectName); if (!lpszTemp) { RRETURN(S_FALSE); }
*lppszObjectName = AllocADsStr(lpszTemp); if (!(*lppszObjectName)) { RRETURN(S_FALSE); }
if(lpszTemp){ FreeUnicodeString(lpszTemp); }
RRETURN(hr);
error: *lppszObjectName = NULL; pdwResumeObjectID = NULL;
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiValidateObject
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiValidateObject( NWCONN_HANDLE hConn, NWOBJ_TYPE dwObjType, LPWSTR lpszObjectName, DWORD *pdwResumeObjectID ) { HRESULT hr = S_OK; NWCCODE ccode = SUCCESSFUL; CHAR szAnsiObjectName[OBJ_NAME_SIZE + 1]; CHAR szObjectName[OBJ_NAME_SIZE + 1]; NWOBJ_TYPE pdwObjType = 0xFFFF; NWFLAGS pucHasProperties; NWFLAGS pucObjectFlags; NWFLAGS pucObjSecurity;
//
// Convert BSTR into an ANSI representation required by NW APIs. "0" is
// passed to UnicodeToAnsiString when the length of the string is unknown.
//
UnicodeToAnsiString( lpszObjectName, szAnsiObjectName, 0 );
//
// This call will fail and return 0xffff if the user is not authenticated
// on the server to which the hConn handle is attached to.
//
ccode = NWScanObject( hConn, szAnsiObjectName, dwObjType, pdwResumeObjectID, szObjectName, &pdwObjType, &pucHasProperties, &pucObjectFlags, &pucObjSecurity );
hr = HRESULT_FROM_NWCCODE(ccode);
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiGetAnyBinderyHandle
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiGetAnyBinderyHandle( NWCONN_HANDLE *phConn ) { HRESULT hr = S_OK; NWCCODE ccode = 0; nchar aServerName[OBJ_NAME_SIZE+1];
nuint32 connRef = 0;
ccode = NWCCGetPrimConnRef( &connRef ); hr = HRESULT_FROM_NWCCODE(ccode); BAIL_ON_FAILURE(hr); ccode = NWCCOpenConnByRef( connRef, NWCC_OPEN_UNLICENSED, NWCC_RESERVED, phConn ); hr = HRESULT_FROM_NWCCODE(ccode);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
//
// Function: NWApiGetObjectName
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiGetObjectName( NWCONN_HANDLE hConn, DWORD dwObjectID, LPWSTR *lppszObjectName ) { CHAR szObjectName[OBJ_NAME_SIZE + 1]; HRESULT hr = S_OK; LPWSTR lpszTemp = NULL; NWCCODE ccode = SUCCESSFUL; NWOBJ_TYPE dwObjType;
ccode = NWGetObjectName( hConn, dwObjectID, szObjectName, &dwObjType ); hr = HRESULT_FROM_NWCCODE(ccode); BAIL_ON_FAILURE(hr);
lpszTemp = AllocateUnicodeString(szObjectName); if (!lpszTemp) { RRETURN(S_FALSE); }
*lppszObjectName = AllocADsStr(lpszTemp); if (!(*lppszObjectName)) { RRETURN(S_FALSE); }
FreeUnicodeString(lpszTemp);
RRETURN(hr);
error: *lppszObjectName = NULL;
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: HRESULT_FROM_NWCCODE
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT HRESULT_FROM_NWCCODE( NWCCODE ccode ) { HRESULT hr = S_OK;
if (ccode == NO_SUCH_PROPERTY) { hr = E_ADS_PROPERTY_NOT_FOUND; } else if (ccode != SUCCESSFUL) {
hr = HRESULT_FROM_WIN32(ERROR_EXTENDED_ERROR); }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiOpenPrinter
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiOpenPrinter( LPWSTR lpszUncPrinterName, HANDLE *phPrinter, DWORD dwAccess ) { BOOL fStatus = TRUE; HANDLE hPrinter; HRESULT hr = S_OK; PRINTER_DEFAULTS PrinterDefault = {0, 0, dwAccess};
//
// Set desired access right.
//
PrinterDefault.DesiredAccess = dwAccess;
//
// Get a handle to the speccified printer using Win32 API.
//
fStatus = OpenPrinter( lpszUncPrinterName, &hPrinter, &PrinterDefault );
//
// Convert error code into HRESULT.
//
if (fStatus == FALSE) { hr = HRESULT_FROM_WIN32(GetLastError()); }
//
// Return.
//
else { *phPrinter = hPrinter; }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiClosePrinter
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiClosePrinter( HANDLE hPrinter ) { BOOL fStatus = TRUE; HRESULT hr = S_OK;
//
// Close a printer using Win32 API.
//
fStatus = ClosePrinter(hPrinter);
//
// Convert error code into HRESULT.
//
if (fStatus == FALSE) { hr = HRESULT_FROM_WIN32(GetLastError()); }
//
// Return.
//
RRETURN(hr); }
/* BUGBUG
//----------------------------------------------------------------------------
//
// Function: NWApiEnumJobs
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiEnumJobs( HANDLE hPrinter, DWORD dwFirstJob, DWORD dwNoJobs, DWORD dwLevel, LPBYTE *lplpbJobs, DWORD *pcbBuf, LPDWORD lpdwReturned ) { BOOL fStatus = TRUE; HRESULT hr = S_OK;
fStatus = WinNTEnumJobs( hPrinter, dwFirstJob, dwNoJobs, dwLevel, lplpbJobs, pcbBuf, lpdwReturned );
if (fStatus == FALSE) { hr = HRESULT_FROM_WIN32(GetLastError()); }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiGetPrinter
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiGetPrinter( HANDLE hPrinter, DWORD dwLevel, LPBYTE *lplpbPrinters ) { BOOL fStatus = TRUE; HRESULT hr = S_OK;
fStatus = WinNTGetPrinter( hPrinter, dwLevel, lplpbPrinters );
if (fStatus == FALSE) { hr = HRESULT_FROM_WIN32(GetLastError()); }
RRETURN(hr); }
*/
//----------------------------------------------------------------------------
//
// Function: NWApiSetPrinter
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiSetPrinter( HANDLE hPrinter, DWORD dwLevel, LPBYTE lpbPrinters, DWORD dwAccess ) { BOOL fStatus = FALSE; HRESULT hr = S_OK;
fStatus = SetPrinter( hPrinter, dwLevel, lpbPrinters, dwAccess ); if (!fStatus) { goto error; }
RRETURN(S_OK);
error:
hr = HRESULT_FROM_WIN32(GetLastError());
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiGetJob
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiGetJob( HANDLE hPrinter, DWORD dwJobId, DWORD dwLevel, LPBYTE *lplpbJobs ) { BOOL fStatus = FALSE; DWORD dwError = 0; DWORD dwNeeded = 0; DWORD dwPassed = 1024; LPBYTE pMem = NULL;
//
// Allocate memory for return buffer.
//
pMem = (LPBYTE)AllocADsMem(dwPassed); if (!pMem) { RRETURN(E_OUTOFMEMORY); }
//
// Get Job's information.
//
fStatus = GetJob( hPrinter, dwJobId, dwLevel, pMem, dwPassed, &dwNeeded );
//
// Get job's information again with a bigger buffer if a bigger buffer is
// needed for the result.
//
if (!fStatus) {
if ((dwError = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) { RRETURN(HRESULT_FROM_WIN32(dwError)); }
if (pMem){ FreeADsMem(pMem); }
pMem = (LPBYTE)AllocADsMem( dwNeeded );
if (!pMem) { RRETURN(E_OUTOFMEMORY); }
dwPassed = dwNeeded;
fStatus = GetJob( hPrinter, dwJobId, dwLevel, pMem, dwPassed, &dwNeeded );
if (!fStatus) { RRETURN(HRESULT_FROM_WIN32(GetLastError())); } }
//
// Return.
//
*lplpbJobs = pMem;
RRETURN(S_OK); }
//----------------------------------------------------------------------------
//
// Function: NWApiSetJob
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT NWApiSetJob( HANDLE hPrinter, DWORD dwJobId, DWORD dwLevel, LPBYTE lpbJobs, DWORD dwCommand ) { BOOL fStatus = FALSE; HRESULT hr = S_OK;
fStatus = SetJob( hPrinter, dwJobId, dwLevel, lpbJobs, dwCommand ); if (!fStatus) { goto error; }
RRETURN(S_OK);
error:
hr = HRESULT_FROM_WIN32(GetLastError());
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: NWApiCreateProperty
//
// Synopsis: This function creates a bindery property. Access is logged read,
// supervisor write.
//
//----------------------------------------------------------------------------
HRESULT NWApiCreateProperty( NWCONN_HANDLE hConn, LPWSTR lpszObjectName, NWOBJ_TYPE wObjType, LPSTR lpszPropertyName, NWFLAGS ucObjectFlags ) { CHAR szAnsiObjectName[OBJ_NAME_SIZE + 1]; CHAR szPropertyName[OBJ_NAME_SIZE + 1]; HRESULT hr = S_OK; NWCCODE ccode = SUCCESSFUL;
//
// Convert BSTR into an ANSI representation required by NW APIs. "0" is
// passed to UnicodeToAnsiString when the length of the string is unknown.
//
UnicodeToAnsiString( lpszObjectName, szAnsiObjectName, 0 );
strcpy(szPropertyName, lpszPropertyName);
//
// Create property.
//
ccode = NWCreateProperty( hConn, szAnsiObjectName, wObjType, szPropertyName, ucObjectFlags, BS_LOGGED_READ | BS_SUPER_WRITE ); //
// Return.
//
hr = HRESULT_FROM_NWCCODE(ccode);
RRETURN(hr); }
|