Fossil SCM
Possible fix for [56bafbab54]: unable to use network drive. Theory is that the AccessCheck() call failes because there are more than one Privileges in use. See: [http://msdn.microsoft.com/en-us/library/windows/desktop/aa374815%28v=vs.85%29.aspx]
Commit
969f0a2611bcc83cb0b8ddb6020bb94a8a569132
Parent
f6ac1ff032dc5d6…
1 file changed
+22
-5
+22
-5
| --- src/winfile.c | ||
| +++ src/winfile.c | ||
| @@ -54,21 +54,21 @@ | ||
| 54 | 54 | ** 8.6 and then modified. |
| 55 | 55 | */ |
| 56 | 56 | int win32_access(const wchar_t *zFilename, int flags){ |
| 57 | 57 | int rc = 0; |
| 58 | 58 | PSECURITY_DESCRIPTOR pSd = NULL; |
| 59 | - unsigned long size; | |
| 59 | + unsigned long size = 0; | |
| 60 | 60 | PSID pSid = NULL; |
| 61 | 61 | BOOL sidDefaulted; |
| 62 | 62 | BOOL impersonated = FALSE; |
| 63 | 63 | SID_IDENTIFIER_AUTHORITY unmapped = {{0, 0, 0, 0, 0, 22}}; |
| 64 | 64 | GENERIC_MAPPING genMap; |
| 65 | 65 | HANDLE hToken = NULL; |
| 66 | 66 | DWORD desiredAccess = 0, grantedAccess = 0; |
| 67 | 67 | BOOL accessYesNo = FALSE; |
| 68 | - PRIVILEGE_SET privSet; | |
| 69 | - DWORD privSetSize = sizeof(PRIVILEGE_SET); | |
| 68 | + PPRIVILEGE_SET pPrivSet = NULL; | |
| 69 | + DWORD privSetSize = 0; | |
| 70 | 70 | DWORD attr = GetFileAttributesW(zFilename); |
| 71 | 71 | |
| 72 | 72 | if( attr==INVALID_FILE_ATTRIBUTES ){ |
| 73 | 73 | /* |
| 74 | 74 | * File might not exist. |
| @@ -110,11 +110,10 @@ | ||
| 110 | 110 | |
| 111 | 111 | /* |
| 112 | 112 | * First find out how big the buffer needs to be. |
| 113 | 113 | */ |
| 114 | 114 | |
| 115 | - size = 0; | |
| 116 | 115 | GetFileSecurityW(zFilename, |
| 117 | 116 | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | |
| 118 | 117 | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, |
| 119 | 118 | 0, 0, &size); |
| 120 | 119 | |
| @@ -213,16 +212,31 @@ | ||
| 213 | 212 | memset(&genMap, 0, sizeof(GENERIC_MAPPING)); |
| 214 | 213 | genMap.GenericRead = FILE_GENERIC_READ; |
| 215 | 214 | genMap.GenericWrite = FILE_GENERIC_WRITE; |
| 216 | 215 | genMap.GenericExecute = FILE_GENERIC_EXECUTE; |
| 217 | 216 | genMap.GenericAll = FILE_ALL_ACCESS; |
| 217 | + | |
| 218 | + AccessCheck(pSd, hToken, desiredAccess, &genMap, 0, | |
| 219 | + &privSetSize, &grantedAccess, &accessYesNo); | |
| 220 | + /* | |
| 221 | + * Should have failed with ERROR_INSUFFICIENT_BUFFER | |
| 222 | + */ | |
| 223 | + | |
| 224 | + if( GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ | |
| 225 | + rc = -1; goto done; | |
| 226 | + } | |
| 227 | + pPrivSet = (PPRIVILEGE_SET)HeapAlloc(GetProcessHeap(), 0, privSetSize); | |
| 228 | + | |
| 229 | + if( pPrivSet==NULL ){ | |
| 230 | + rc = -1; goto done; | |
| 231 | + } | |
| 218 | 232 | |
| 219 | 233 | /* |
| 220 | 234 | * Perform access check using the token. |
| 221 | 235 | */ |
| 222 | 236 | |
| 223 | - if( !AccessCheck(pSd, hToken, desiredAccess, &genMap, &privSet, | |
| 237 | + if( !AccessCheck(pSd, hToken, desiredAccess, &genMap, pPrivSet, | |
| 224 | 238 | &privSetSize, &grantedAccess, &accessYesNo) ){ |
| 225 | 239 | /* |
| 226 | 240 | * Unable to perform access check. |
| 227 | 241 | */ |
| 228 | 242 | |
| @@ -237,10 +251,13 @@ | ||
| 237 | 251 | } |
| 238 | 252 | if( impersonated ){ |
| 239 | 253 | RevertToSelf(); |
| 240 | 254 | impersonated = FALSE; |
| 241 | 255 | } |
| 256 | + if( pPrivSet!=NULL ){ | |
| 257 | + HeapFree(GetProcessHeap(), 0, pPrivSet); | |
| 258 | + } | |
| 242 | 259 | if( pSd!=NULL ){ |
| 243 | 260 | HeapFree(GetProcessHeap(), 0, pSd); |
| 244 | 261 | } |
| 245 | 262 | return rc; |
| 246 | 263 | } |
| 247 | 264 |
| --- src/winfile.c | |
| +++ src/winfile.c | |
| @@ -54,21 +54,21 @@ | |
| 54 | ** 8.6 and then modified. |
| 55 | */ |
| 56 | int win32_access(const wchar_t *zFilename, int flags){ |
| 57 | int rc = 0; |
| 58 | PSECURITY_DESCRIPTOR pSd = NULL; |
| 59 | unsigned long size; |
| 60 | PSID pSid = NULL; |
| 61 | BOOL sidDefaulted; |
| 62 | BOOL impersonated = FALSE; |
| 63 | SID_IDENTIFIER_AUTHORITY unmapped = {{0, 0, 0, 0, 0, 22}}; |
| 64 | GENERIC_MAPPING genMap; |
| 65 | HANDLE hToken = NULL; |
| 66 | DWORD desiredAccess = 0, grantedAccess = 0; |
| 67 | BOOL accessYesNo = FALSE; |
| 68 | PRIVILEGE_SET privSet; |
| 69 | DWORD privSetSize = sizeof(PRIVILEGE_SET); |
| 70 | DWORD attr = GetFileAttributesW(zFilename); |
| 71 | |
| 72 | if( attr==INVALID_FILE_ATTRIBUTES ){ |
| 73 | /* |
| 74 | * File might not exist. |
| @@ -110,11 +110,10 @@ | |
| 110 | |
| 111 | /* |
| 112 | * First find out how big the buffer needs to be. |
| 113 | */ |
| 114 | |
| 115 | size = 0; |
| 116 | GetFileSecurityW(zFilename, |
| 117 | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | |
| 118 | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, |
| 119 | 0, 0, &size); |
| 120 | |
| @@ -213,16 +212,31 @@ | |
| 213 | memset(&genMap, 0, sizeof(GENERIC_MAPPING)); |
| 214 | genMap.GenericRead = FILE_GENERIC_READ; |
| 215 | genMap.GenericWrite = FILE_GENERIC_WRITE; |
| 216 | genMap.GenericExecute = FILE_GENERIC_EXECUTE; |
| 217 | genMap.GenericAll = FILE_ALL_ACCESS; |
| 218 | |
| 219 | /* |
| 220 | * Perform access check using the token. |
| 221 | */ |
| 222 | |
| 223 | if( !AccessCheck(pSd, hToken, desiredAccess, &genMap, &privSet, |
| 224 | &privSetSize, &grantedAccess, &accessYesNo) ){ |
| 225 | /* |
| 226 | * Unable to perform access check. |
| 227 | */ |
| 228 | |
| @@ -237,10 +251,13 @@ | |
| 237 | } |
| 238 | if( impersonated ){ |
| 239 | RevertToSelf(); |
| 240 | impersonated = FALSE; |
| 241 | } |
| 242 | if( pSd!=NULL ){ |
| 243 | HeapFree(GetProcessHeap(), 0, pSd); |
| 244 | } |
| 245 | return rc; |
| 246 | } |
| 247 |
| --- src/winfile.c | |
| +++ src/winfile.c | |
| @@ -54,21 +54,21 @@ | |
| 54 | ** 8.6 and then modified. |
| 55 | */ |
| 56 | int win32_access(const wchar_t *zFilename, int flags){ |
| 57 | int rc = 0; |
| 58 | PSECURITY_DESCRIPTOR pSd = NULL; |
| 59 | unsigned long size = 0; |
| 60 | PSID pSid = NULL; |
| 61 | BOOL sidDefaulted; |
| 62 | BOOL impersonated = FALSE; |
| 63 | SID_IDENTIFIER_AUTHORITY unmapped = {{0, 0, 0, 0, 0, 22}}; |
| 64 | GENERIC_MAPPING genMap; |
| 65 | HANDLE hToken = NULL; |
| 66 | DWORD desiredAccess = 0, grantedAccess = 0; |
| 67 | BOOL accessYesNo = FALSE; |
| 68 | PPRIVILEGE_SET pPrivSet = NULL; |
| 69 | DWORD privSetSize = 0; |
| 70 | DWORD attr = GetFileAttributesW(zFilename); |
| 71 | |
| 72 | if( attr==INVALID_FILE_ATTRIBUTES ){ |
| 73 | /* |
| 74 | * File might not exist. |
| @@ -110,11 +110,10 @@ | |
| 110 | |
| 111 | /* |
| 112 | * First find out how big the buffer needs to be. |
| 113 | */ |
| 114 | |
| 115 | GetFileSecurityW(zFilename, |
| 116 | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | |
| 117 | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, |
| 118 | 0, 0, &size); |
| 119 | |
| @@ -213,16 +212,31 @@ | |
| 212 | memset(&genMap, 0, sizeof(GENERIC_MAPPING)); |
| 213 | genMap.GenericRead = FILE_GENERIC_READ; |
| 214 | genMap.GenericWrite = FILE_GENERIC_WRITE; |
| 215 | genMap.GenericExecute = FILE_GENERIC_EXECUTE; |
| 216 | genMap.GenericAll = FILE_ALL_ACCESS; |
| 217 | |
| 218 | AccessCheck(pSd, hToken, desiredAccess, &genMap, 0, |
| 219 | &privSetSize, &grantedAccess, &accessYesNo); |
| 220 | /* |
| 221 | * Should have failed with ERROR_INSUFFICIENT_BUFFER |
| 222 | */ |
| 223 | |
| 224 | if( GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ |
| 225 | rc = -1; goto done; |
| 226 | } |
| 227 | pPrivSet = (PPRIVILEGE_SET)HeapAlloc(GetProcessHeap(), 0, privSetSize); |
| 228 | |
| 229 | if( pPrivSet==NULL ){ |
| 230 | rc = -1; goto done; |
| 231 | } |
| 232 | |
| 233 | /* |
| 234 | * Perform access check using the token. |
| 235 | */ |
| 236 | |
| 237 | if( !AccessCheck(pSd, hToken, desiredAccess, &genMap, pPrivSet, |
| 238 | &privSetSize, &grantedAccess, &accessYesNo) ){ |
| 239 | /* |
| 240 | * Unable to perform access check. |
| 241 | */ |
| 242 | |
| @@ -237,10 +251,13 @@ | |
| 251 | } |
| 252 | if( impersonated ){ |
| 253 | RevertToSelf(); |
| 254 | impersonated = FALSE; |
| 255 | } |
| 256 | if( pPrivSet!=NULL ){ |
| 257 | HeapFree(GetProcessHeap(), 0, pPrivSet); |
| 258 | } |
| 259 | if( pSd!=NULL ){ |
| 260 | HeapFree(GetProcessHeap(), 0, pSd); |
| 261 | } |
| 262 | return rc; |
| 263 | } |
| 264 |