From: Jeffrey Altman Date: Thu, 7 Mar 2013 05:54:32 +0000 (-0500) Subject: Windows: GetReparseData UNC path format X-Git-Tag: openafs-stable-1_8_0pre1~1313 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=241382e3bf588269b5115fea1be0f782de43ca2a Windows: GetReparseData UNC path format When specifying UNC paths for Symlink and UNCLink targets output the paths using true UNC notation "\\server\..." instead of "\server\...". Change-Id: I51ecc6578fb0a984a5ad44b1bf1e40556e737465 Reviewed-on: http://gerrit.openafs.org/9426 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp index d8a9d22..ec0acf5 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp @@ -160,6 +160,7 @@ AFSProcessUserFsRequest( IN PIRP Irp) PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp ); AFSCcb *pCcb = NULL; ULONG ulOutputBufferLen, ulInputBufferLen; + BOOLEAN bRelative = FALSE; __Enter { @@ -420,29 +421,49 @@ AFSProcessUserFsRequest( IN PIRP Irp) break; } - if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length) + bRelative = AFSIsRelativeName( &pCcb->DirectoryCB->NameInformation.TargetName); + + if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + + pCcb->DirectoryCB->NameInformation.TargetName.Length + (bRelative ? 0 : sizeof( WCHAR))) { ntStatus = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + - pCcb->DirectoryCB->NameInformation.TargetName.Length; + pCcb->DirectoryCB->NameInformation.TargetName.Length + + (bRelative ? 0 : sizeof( WCHAR)); break; } pReparseInfo->SubTag = OPENAFS_SUBTAG_SYMLINK; - pReparseInfo->AFSSymLink.RelativeLink = AFSIsRelativeName( &pCcb->DirectoryCB->NameInformation.TargetName); + pReparseInfo->AFSSymLink.RelativeLink = bRelative; pReparseInfo->AFSSymLink.SymLinkTargetLength = pCcb->DirectoryCB->NameInformation.TargetName.Length; - RtlCopyMemory( pReparseInfo->AFSSymLink.Buffer, - pCcb->DirectoryCB->NameInformation.TargetName.Buffer, - pCcb->DirectoryCB->NameInformation.TargetName.Length); + if ( pReparseInfo->AFSSymLink.RelativeLink == FALSE) + { + + pReparseInfo->AFSSymLink.Buffer[0] = L'\\'; + + RtlCopyMemory( &pReparseInfo->AFSSymLink.Buffer[ 1], + pCcb->DirectoryCB->NameInformation.TargetName.Buffer, + pCcb->DirectoryCB->NameInformation.TargetName.Length); + + pReparseInfo->AFSSymLink.SymLinkTargetLength += sizeof( WCHAR); + } + else + { + + RtlCopyMemory( pReparseInfo->AFSSymLink.Buffer, + pCcb->DirectoryCB->NameInformation.TargetName.Buffer, + pCcb->DirectoryCB->NameInformation.TargetName.Length); + } - pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length); + pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + + pReparseInfo->AFSSymLink.SymLinkTargetLength); break; } @@ -513,14 +534,17 @@ AFSProcessUserFsRequest( IN PIRP Irp) break; } - if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length) + if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + + pCcb->DirectoryCB->NameInformation.TargetName.Length + + (pCcb->DirectoryCB->NameInformation.TargetName.Buffer[0] == L'\\' ? sizeof( WCHAR) : 0)) { ntStatus = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + - pCcb->DirectoryCB->NameInformation.TargetName.Length; + pCcb->DirectoryCB->NameInformation.TargetName.Length + + (pCcb->DirectoryCB->NameInformation.TargetName.Buffer[0] == L'\\' ? sizeof( WCHAR) : 0); break; } @@ -529,11 +553,27 @@ AFSProcessUserFsRequest( IN PIRP Irp) pReparseInfo->UNCReferral.UNCTargetLength = pCcb->DirectoryCB->NameInformation.TargetName.Length; - RtlCopyMemory( pReparseInfo->UNCReferral.Buffer, - pCcb->DirectoryCB->NameInformation.TargetName.Buffer, - pCcb->DirectoryCB->NameInformation.TargetName.Length); + if ( pCcb->DirectoryCB->NameInformation.TargetName.Buffer[0] == L'\\') + { + + pReparseInfo->UNCReferral.Buffer[0] = L'\\'; + + RtlCopyMemory( &pReparseInfo->UNCReferral.Buffer[ 1], + pCcb->DirectoryCB->NameInformation.TargetName.Buffer, + pCcb->DirectoryCB->NameInformation.TargetName.Length); + + pReparseInfo->UNCReferral.UNCTargetLength += sizeof( WCHAR); + } + else + { + + RtlCopyMemory( pReparseInfo->UNCReferral.Buffer, + pCcb->DirectoryCB->NameInformation.TargetName.Buffer, + pCcb->DirectoryCB->NameInformation.TargetName.Length); + } - pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length); + pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + + pReparseInfo->UNCReferral.UNCTargetLength); break; }