smbmrxnp.c
来自「winddk src目录下的文件系统驱动源码压缩!」· C语言 代码 · 共 1,729 行 · 第 1/4 页
C
1,729 行
lpUserName - the user name
dwFlags - flags for the connection
Return Value:
WN_SUCCESS if successful, otherwise the appropriate error
Notes:
The current sample does not handle explicitly passesd in credentials. Normally
the credential information is passed in as EA parameters to the associated
mini redirector for further manipulation
--*/
{
DWORD Status = 0;
UNICODE_STRING ConnectionName;
PWCHAR pLocalName,pRemoteName;
USHORT LocalNameLength,RemoteNameLength;
HANDLE hConnection;
ULONG TransferBytes;
WCHAR NullStr[] = L"\0\0";
PWCHAR pUserName;
PWCHAR pPassword;
PWKSTA_USER_INFO_0 WkStaUserInfo;
PSMBMRX_CONNECTINFO ConnectInfo;
DbgP((TEXT("NPAddConnection3: Incoming UserName - %s, Password - %s\n"),
lpUserName, lpPassword ));
// if no user specified, get the current logged on user
if ( lpUserName == NULL )
{
Status = NetWkstaUserGetInfo( NULL, 0, (PBYTE *)&WkStaUserInfo );
if ( Status == ERROR_SUCCESS )
{
pUserName = WkStaUserInfo->wkui0_username;
}
else
{
pUserName = NullStr;
}
}
else
{
pUserName = lpUserName;
}
if ( lpPassword == NULL )
{
pPassword = NullStr; // use default password
pPassword[1] = '\0'; // reset empty flag
}
else if ( *lpPassword == L'\0' )
{
pPassword = NullStr;
pPassword[1] = '1'; // flag the password as "Empty"
}
else
{
pPassword = lpPassword;
}
Status = ERROR_SUCCESS;
DbgP((TEXT("NPAddConnection3: Outgoing UserName - %s, Password - %s\n"),
lpUserName, lpPassword ));
// The SMB mini supports only DISK type resources. The other resources
// are not supported.
if ((lpNetResource->lpRemoteName == NULL) ||
(lpNetResource->lpRemoteName[0] != L'\\') ||
(lpNetResource->lpRemoteName[1] != L'\\') ||
(lpNetResource->dwType != RESOURCETYPE_DISK))
{
return WN_BAD_NETNAME;
}
//
// The remote name is in the UNC format \\Server\Share. This name
// needs to be translated to an appropriate NT name in order to
// issue the request to the underlying mini redirector to create the
// connection.
//
// The NT style name is of the form
//
// \device\smbminiredirector\;<DriveLetter>:\Server\Share
//
// The additional ; is required by the new RDR for extensibility.
//
pLocalName = lpNetResource->lpLocalName;
pRemoteName = lpNetResource->lpRemoteName;
// skip past the first back slash since the name to be appended for the
// NT name does not require this.
pRemoteName++;
if (pLocalName != NULL) {
LocalNameLength = wcslen(pLocalName) * sizeof(WCHAR);
} else {
LocalNameLength = 0;
}
RemoteNameLength = (wcslen(pRemoteName) - 1) * sizeof(WCHAR);
ConnectionName.MaximumLength = (USHORT)(SmbMRxDeviceName.Length +
(USHORT)RemoteNameLength +
((pLocalName != NULL)
? (LocalNameLength + sizeof(WCHAR)) : 0) + // space for ;
sizeof(WCHAR));
ConnectionName.Length = ConnectionName.MaximumLength;
ConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
ConnectionName.Length + sizeof(WCHAR));
if (ConnectionName.Buffer == NULL)
{
return GetLastError();
}
// Copy the name into the buffer
CopyMemory( ConnectionName.Buffer,
SmbMRxDeviceName.Buffer,
SmbMRxDeviceName.Length);
wcscat(ConnectionName.Buffer, L"\\");
wcscat(ConnectionName.Buffer, L";");
if (pLocalName != NULL)
{
wcscat(ConnectionName.Buffer, pLocalName);
}
wcscat(ConnectionName.Buffer, pRemoteName);
ConnectInfo = (PSMBMRX_CONNECTINFO) LocalAlloc( LMEM_ZEROINIT, MAX_CONNECT_INFO_SIZE );
if ( ConnectInfo )
{
ConnectInfo->ConnectionNameOffset = 0;
ConnectInfo->ConnectionNameLength = ConnectionName.Length;
CopyMemory( ConnectInfo->InfoArea, ConnectionName.Buffer, ConnectionName.Length );
ConnectInfo->EaDataOffset = ConnectInfo->ConnectionNameOffset +
ConnectInfo->ConnectionNameLength;
// check for the "no password" flag
if ( pPassword[0] == L'\0' && pPassword[1] == L'1' )
{
pPassword = NULL;
}
ConnectInfo->EaDataLength = FillInEaBuffer( pUserName,
pPassword,
(PBYTE) ConnectInfo->InfoArea +
ConnectInfo->EaDataOffset );
TransferBytes = 0;
Status = SendToMiniRdr( IOCTL_SMBMRX_ADDCONN,
ConnectInfo,
MAX_CONNECT_INFO_SIZE,
NULL,
&TransferBytes );
LocalFree( ConnectInfo );
}
else
{
Status = WN_OUT_OF_MEMORY;
}
if ((Status == WN_SUCCESS) && (pLocalName != NULL))
{
WCHAR TempBuf[64];
if (!QueryDosDeviceW(
pLocalName,
TempBuf,
64))
{
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
//
// Most likely failure occurred because our output
// buffer is too small. It still means someone already
// has an existing symbolic link for this device.
//
Status = ERROR_ALREADY_ASSIGNED;
}
else
{
//
// ERROR_FILE_NOT_FOUND (translated from OBJECT_NAME_NOT_FOUND)
// means it does not exist and we can redirect this device.
//
// Create a symbolic link object to the device we are redirecting
//
if (!DefineDosDeviceW(
DDD_RAW_TARGET_PATH |
DDD_NO_BROADCAST_SYSTEM,
pLocalName,
ConnectionName.Buffer))
{
Status = GetLastError();
}
else
{
Status = WN_SUCCESS;
}
}
}
else
{
//
// QueryDosDevice successfully an existing symbolic link--
// somebody is already using this device.
//
Status = ERROR_ALREADY_ASSIGNED;
}
}
else
{
DbgP((TEXT("SendToMiniRdr returned %lx\n"),Status));
}
if (Status == WN_SUCCESS)
{
INT Index;
HANDLE hMutex, hMemory;
BOOLEAN FreeEntryFound = FALSE;
PSMBMRXNP_SHARED_MEMORY pSharedMemory;
// The connection was established and the local device mapping
// added. Include this in the list of mapped devices.
Status = OpenSharedMemory(
&hMutex,
&hMemory,
(PVOID)&pSharedMemory);
if (Status == WN_SUCCESS)
{
DbgP((TEXT("NPAddConnection3: Highest Index %d Number Of resources %d\n"),
pSharedMemory->HighestIndexInUse,pSharedMemory->NumberOfResourcesInUse));
Index = 0;
while (Index < pSharedMemory->HighestIndexInUse)
{
if (!pSharedMemory->NetResources[Index].InUse)
{
FreeEntryFound = TRUE;
break;
}
Index++;
}
if (!FreeEntryFound &&
(pSharedMemory->HighestIndexInUse < SMBMRXNP_MAX_DEVICES))
{
pSharedMemory->HighestIndexInUse += 1;
Index = pSharedMemory->HighestIndexInUse;
FreeEntryFound = TRUE;
}
if (FreeEntryFound)
{
PSMBMRXNP_NETRESOURCE pSmbMrxNetResource;
pSharedMemory->NumberOfResourcesInUse += 1;
pSmbMrxNetResource = &pSharedMemory->NetResources[Index];
pSmbMrxNetResource->InUse = TRUE;
pSmbMrxNetResource->dwScope = lpNetResource->dwScope;
pSmbMrxNetResource->dwType = lpNetResource->dwType;
pSmbMrxNetResource->dwDisplayType = lpNetResource->dwDisplayType;
pSmbMrxNetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
pSmbMrxNetResource->LocalNameLength = LocalNameLength;
pSmbMrxNetResource->RemoteNameLength = wcslen(lpNetResource->lpRemoteName) * sizeof(WCHAR);
pSmbMrxNetResource->ConnectionNameLength = ConnectionName.Length;
// Copy the local name
CopyMemory( pSmbMrxNetResource->LocalName,
lpNetResource->lpLocalName,
pSmbMrxNetResource->LocalNameLength);
// Copy the remote name
CopyMemory( pSmbMrxNetResource->RemoteName,
lpNetResource->lpRemoteName,
pSmbMrxNetResource->RemoteNameLength);
// Copy the connection name
CopyMemory( pSmbMrxNetResource->ConnectionName,
ConnectionName.Buffer,
pSmbMrxNetResource->ConnectionNameLength);
//
// Copy the Auth info
//
// WARNING : security hole using shared memory..Developers must use alternate methods to maintain use table.
//
lstrcpyn( pSmbMrxNetResource->UserName, pUserName, MAX_PATH);
if ( *pPassword )
{
lstrcpyn( pSmbMrxNetResource->Password, pPassword, MAX_PATH);
}
else
{
CopyMemory( pSmbMrxNetResource->Password, pPassword, 3 * sizeof(WCHAR) );
}
}
else
{
Status = WN_NO_MORE_DEVICES;
}
CloseSharedMemory( &hMutex,
&hMemory,
(PVOID)&pSharedMemory);
}
else
{
DbgP((TEXT("NpAddConnection3: OpenSharedMemory returned %lx\n"),Status));
}
}
return Status;
}
DWORD APIENTRY
NPCancelConnection(
LPWSTR lpName,
BOOL fForce )
/*++
Routine Description:
This routine cancels ( deletes ) a connection from the list of connections
associated with this network provider
Arguments:
lpName - name of the connection
fForce - forcefully delete the connection
Return Value:
WN_SUCCESS if successful, otherwise the appropriate error
Notes:
--*/
{
BOOL bLocalName = TRUE;
DWORD Status = 0;
UNICODE_STRING Name;
HANDLE hMutex, hMemory;
PSMBMRXNP_SHARED_MEMORY pSharedMemory;
if (*lpName == L'\\' && *(lpName + 1) == L'\\')
{
bLocalName = FALSE;
}
DbgP((TEXT("NPCancelConnection\n")));
DbgP((TEXT("NPCancelConnection: ConnectionName: %S\n"), lpName));
Name.MaximumLength = Name.Length = wcslen(lpName) * sizeof(WCHAR);
Name.Buffer = lpName;
Status = OpenSharedMemory( &hMutex,
&hMemory,
(PVOID)&pSharedMemory);
if (Status == WN_SUCCESS)
{
INT Index;
BOOL EntryFound = FALSE;
PSMBMRXNP_NETRESOURCE pNetResource;
DbgP((TEXT("NPCancelConnection: Highest Index %d Number Of resources %d\n"),
pSharedMemory->HighestIndexInUse,pSharedMemory->NumberOfResourcesInUse));
for (Index = 0; Index <= pSharedMemory->HighestIndexInUse; Index++)
{
pNetResource = &pSharedMemory->NetResources[Index];
if (pNetResource->InUse)
{
UNICODE_STRING EntryName;
if (bLocalName)
{
EntryName.MaximumLength = pNetResource->LocalNameLength;
EntryName.Length = EntryName.MaximumLength;
EntryName.Buffer = pNetResource->LocalName;
}
else
{
EntryName.MaximumLength = pNetResource->RemoteNameLength;
EntryName.Length = EntryName.MaximumLength;
EntryName.Buffer = pNetResource->RemoteName;
}
DbgP((TEXT("NPCancelConnection: Name %S EntryName %S\n"),
lpName,EntryName.Buffer));
DbgP((TEXT("NPCancelConnection: Name Length %d Entry Name Length %d\n"),
Name.Length,EntryName.Length));
if (Name.Length == EntryName.Length)
{
if ( _wcsnicmp(Name.Buffer, EntryName.Buffer, Name.Length) == 0 )
{
EntryFound = TRUE;
break;
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?