perform correct case resolution in sys_full_path
@@ -415,10 +415,52 @@ HL_PRIM varray *hl_sys_read_dir( vbyte *_path ) {
HL_PRIM vbyte *hl_sys_full_path( vbyte *path ) {
#ifdef HL_WIN
- pchar buf[MAX_PATH+1];
- if( GetFullPathNameW((pchar*)path,MAX_PATH+1,buf,NULL) == 0 )
+ pchar out[MAX_PATH+1];
+ int len, i, last;
+ HANDLE handle;
+ WIN32_FIND_DATA data;
+ const char sep = '\\';
+ if( GetFullPathNameW((pchar*)path,MAX_PATH+1,out,NULL) == 0 )
return NULL;
- return (vbyte*)pstrdup(buf,-1);
+ len = ustrlen(out);
+ i = 0;
+
+ if (len >= 2 && out[1] == ':') {
+ // convert drive letter to uppercase
+ if (out[0] >= 'a' && out[0] <= 'z')
+ out[0] += (pchar)('A' - 'a');
+ if (len >= 3 && out[2] == sep)
+ i = 3;
+ else
+ i = 2;
+ }
+
+ last = i;
+
+ while (i < len) {
+ // skip until separator
+ while (i < len && out[i] != sep)
+ i++;
+
+ // temporarily strip string to last found component
+ out[i] = 0;
+
+ // get actual file/dir name with proper case
+ if ((handle = FindFirstFileW(out, &data)) != INVALID_HANDLE_VALUE) {
+ // replace the component with proper case
+ memcpy(out + last, data.cFileName, i - last);
+ FindClose(handle);
+ }
+
+ // if we're not at the end, restore the path
+ if (i < len)
+ out[i] = sep;
+
+ // advance
+ i++;
+ last = i;
+ }
+ return (vbyte*)pstrdup(out,len);
#else
pchar buf[PATH_MAX];
if( realpath((pchar*)path,buf) == NULL )
