⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dir.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
            SetLastErrorByStatus(Status);
            return 0;
        }

        return RetValue;
}


/*
 * @implemented
 */
DWORD
STDCALL
SearchPathW (
        LPCWSTR lpPath,
        LPCWSTR lpFileName,
        LPCWSTR lpExtension,
        DWORD   nBufferLength,
        LPWSTR  lpBuffer,
        LPWSTR  *lpFilePart
        )
/*
 * FUNCTION: Searches for the specified file
 * ARGUMENTS:
 *       lpPath = Points to a null-terminated string that specified the
 *                path to be searched. If this parameters is NULL then
 *                the following directories are searched
 *                          The directory from which the application loaded
 *                          The current directory
 *                          The system directory
 *                          The 16-bit system directory
 *                          The windows directory
 *                          The directories listed in the PATH environment
 *                          variable
 *        lpFileName = Specifies the filename to search for
 *        lpExtension = Points to the null-terminated string that specifies
 *                      an extension to be added to the filename when
 *                      searching for the file. The first character of the
 *                      filename extension must be a period (.). The
 *                      extension is only added if the specified filename
 *                      doesn't end with an extension
 *
 *                      If the filename extension is not required or if the
 *                      filename contains an extension, this parameters can be
 *                      NULL
 *        nBufferLength = The length in characters of the buffer for output
 *        lpBuffer = Points to the buffer for the valid path and filename of
 *                   file found
 *        lpFilePart = Points to the last component of the valid path and
 *                     filename
 * RETURNS: On success, the length, in characters, of the string copied to the
 *          buffer
 *          On failure, zero.
 */
{
        DWORD retCode = 0;
        ULONG pos, len;
        PWCHAR EnvironmentBufferW = NULL;
        PWCHAR AppPathW = NULL;
        WCHAR Buffer;
        BOOL HasExtension;
        LPCWSTR p;
        PWCHAR Name;

        DPRINT("SearchPath\n");

        HasExtension = FALSE;
        p = lpFileName + wcslen(lpFileName);
        while (lpFileName < p &&
               L'\\' != *(p - 1) &&
               L'/' != *(p - 1) &&
               L':' != *(p - 1))
        {
                HasExtension = HasExtension || L'.' == *(p - 1);
                p--;
        }
        if (lpFileName < p)
        {
                if (HasExtension || NULL == lpExtension)
                {
                        Name = (PWCHAR) lpFileName;
                }
                else
                {
                        Name = RtlAllocateHeap(GetProcessHeap(),
                                               HEAP_GENERATE_EXCEPTIONS,
                                               (wcslen(lpFileName) + wcslen(lpExtension) + 1)
                                               * sizeof(WCHAR));
                        if (NULL == Name)
                        {
                                SetLastError(ERROR_OUTOFMEMORY);
                                return 0;
                        }
                        wcscat(wcscpy(Name, lpFileName), lpExtension);
                }
	        if (RtlDoesFileExists_U(Name))
                {
                        retCode = RtlGetFullPathName_U (Name,
                                                        nBufferLength * sizeof(WCHAR),
                                                        lpBuffer,
                                                        lpFilePart);
                }
                if (Name != lpFileName)
                {
                        RtlFreeHeap(GetProcessHeap(), 0, Name);
                }
        }
        else
        {
                if (lpPath == NULL)
                {

                        AppPathW = (PWCHAR) RtlAllocateHeap(RtlGetProcessHeap(),
                                                        HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
                                                        MAX_PATH * sizeof(WCHAR));
                        if (AppPathW == NULL)
                        {
                            SetLastError(ERROR_OUTOFMEMORY);
                            return 0;
                        }


                        wcscat (AppPathW, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);

                        len = wcslen (AppPathW);

                        while (len && AppPathW[len - 1] != L'\\')
                                len--;

                        if (len) AppPathW[len-1] = L'\0';

                        len = GetEnvironmentVariableW(L"PATH", &Buffer, 0);
                        len += 1 + GetCurrentDirectoryW(0, &Buffer);
                        len += 1 + GetSystemDirectoryW(&Buffer, 0);
                        len += 1 + GetWindowsDirectoryW(&Buffer, 0);
                        len += 1 + wcslen(AppPathW) * sizeof(WCHAR);

                        EnvironmentBufferW = (PWCHAR) RtlAllocateHeap(RtlGetProcessHeap(),
                                                        HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
                                                        len * sizeof(WCHAR));
                        if (EnvironmentBufferW == NULL)
                        {
                                RtlFreeHeap(RtlGetProcessHeap(), 0, AppPathW);
                                SetLastError(ERROR_OUTOFMEMORY);
                                return 0;
                        }

                        pos = GetCurrentDirectoryW(len, EnvironmentBufferW);
                        EnvironmentBufferW[pos++] = L';';
                        EnvironmentBufferW[pos] = 0;
                        pos += GetSystemDirectoryW(&EnvironmentBufferW[pos], len - pos);
                        EnvironmentBufferW[pos++] = L';';
                        EnvironmentBufferW[pos] = 0;
                        pos += GetWindowsDirectoryW(&EnvironmentBufferW[pos], len - pos);
                        EnvironmentBufferW[pos++] = L';';
                        EnvironmentBufferW[pos] = 0;
                        pos += GetEnvironmentVariableW(L"PATH", &EnvironmentBufferW[pos], len - pos);
                        EnvironmentBufferW[pos++] = L';';
                        EnvironmentBufferW[pos] = 0;
                        wcscat (EnvironmentBufferW, AppPathW);

                        RtlFreeHeap (RtlGetProcessHeap (),
                             0,
                             AppPathW);

                        lpPath = EnvironmentBufferW;

                }

                retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension,
                                              nBufferLength * sizeof(WCHAR), lpBuffer, lpFilePart);

                if (EnvironmentBufferW != NULL)
                {
                        RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW);
                }
                if (retCode == 0)
                {
                        SetLastError(ERROR_FILE_NOT_FOUND);
                }
        }
        return retCode / sizeof(WCHAR);
}

/*
 * @implemented
 */
BOOL
STDCALL
SetDllDirectoryW(
    LPCWSTR lpPathName
    )
{
  UNICODE_STRING PathName;

  RtlInitUnicodeString(&PathName, lpPathName);

  RtlEnterCriticalSection(&DllLock);
  if(PathName.Length > 0)
  {
    if(PathName.Length + sizeof(WCHAR) <= DllDirectory.MaximumLength)
    {
      RtlCopyUnicodeString(&DllDirectory, &PathName);
    }
    else
    {
      RtlFreeUnicodeString(&DllDirectory);
      if(!(DllDirectory.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(),
                                                        0,
                                                        PathName.Length + sizeof(WCHAR))))
      {
        RtlLeaveCriticalSection(&DllLock);
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
      }
      DllDirectory.Length = 0;
      DllDirectory.MaximumLength = PathName.Length + sizeof(WCHAR);

      RtlCopyUnicodeString(&DllDirectory, &PathName);
    }
  }
  else
  {
    RtlFreeUnicodeString(&DllDirectory);
  }
  RtlLeaveCriticalSection(&DllLock);

  return TRUE;
}

/*
 * @implemented
 */
BOOL
STDCALL
SetDllDirectoryA(
    LPCSTR lpPathName /* can be NULL */
    )
{
  PWCHAR PathNameW=NULL;

  if(lpPathName)
  {
     if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
        return FALSE;
  }

  return SetDllDirectoryW(PathNameW);
}

/*
 * @implemented
 */
DWORD
STDCALL
GetDllDirectoryW(
    DWORD nBufferLength,
    LPWSTR lpBuffer
    )
{
  DWORD Ret;

  RtlEnterCriticalSection(&DllLock);
  if(nBufferLength > 0)
  {
    Ret = DllDirectory.Length / sizeof(WCHAR);
    if(Ret > nBufferLength - 1)
    {
      Ret = nBufferLength - 1;
    }

    if(Ret > 0)
    {
      RtlCopyMemory(lpBuffer, DllDirectory.Buffer, Ret * sizeof(WCHAR));
    }
    lpBuffer[Ret] = L'\0';
  }
  else
  {
    /* include termination character, even if the string is empty! */
    Ret = (DllDirectory.Length / sizeof(WCHAR)) + 1;
  }
  RtlLeaveCriticalSection(&DllLock);

  return Ret;
}

/*
 * @implemented
 */
DWORD
STDCALL
GetDllDirectoryA(
    DWORD nBufferLength,
    LPSTR lpBuffer
    )
{
  WCHAR BufferW[MAX_PATH];
  DWORD ret;

  ret = GetDllDirectoryW(MAX_PATH, BufferW);

  if (!ret)
     return 0;

  if (ret > MAX_PATH)
  {
     SetLastError(ERROR_FILENAME_EXCED_RANGE);
     return 0;
  }

  return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
}


/*
 * @implemented
 */
BOOL STDCALL
NeedCurrentDirectoryForExePathW(LPCWSTR ExeName)
{
  return (wcschr(ExeName,
                 L'\\') != NULL);
}


/*
 * @implemented
 */
BOOL STDCALL
NeedCurrentDirectoryForExePathA(LPCSTR ExeName)
{
  return (strchr(ExeName,
                 '\\') != NULL);
}





/***********************************************************************
 * @implemented
 *
 *           GetLongPathNameW   (KERNEL32.@)
 *
 * NOTES
 *  observed (Win2000):
 *  shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
 *  shortpath="":   LastError=ERROR_PATH_NOT_FOUND, ret=0
 */
DWORD STDCALL GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen )
{
#define    MAX_PATHNAME_LEN 1024

    WCHAR               tmplongpath[MAX_PATHNAME_LEN];
    LPCWSTR             p;
    DWORD               sp = 0, lp = 0;
    DWORD               tmplen;
    BOOL                unixabsolute = (shortpath[0] == '/');
    WIN32_FIND_DATAW    wfd;
    HANDLE              goit;

    if (!shortpath)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    if (!shortpath[0])
    {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return 0;
    }

    DPRINT("GetLongPathNameW(%s,%p,%ld)\n", shortpath, longpath, longlen);

    if (shortpath[0] == '\\' && shortpath[1] == '\\')
    {
        DPRINT1("ERR: UNC pathname %s\n", shortpath);
        lstrcpynW( longpath, shortpath, longlen );
        return wcslen(longpath);
    }

    /* check for drive letter */
    if (!unixabsolute && shortpath[1] == ':' )
    {
        tmplongpath[0] = shortpath[0];
        tmplongpath[1] = ':';
        lp = sp = 2;
    }

    while (shortpath[sp])
    {
        /* check for path delimiters and reproduce them */
        if (shortpath[sp] == '\\' || shortpath[sp] == '/')
        {
            if (!lp || tmplongpath[lp-1] != '\\')
            {
                /* strip double "\\" */
                tmplongpath[lp++] = '\\';
            }
            tmplongpath[lp] = 0; /* terminate string */
            sp++;
            continue;
        }

        p = shortpath + sp;
        if (sp == 0 && p[0] == '.' && (p[1] == '/' || p[1] == '\\'))
        {
            tmplongpath[lp++] = *p++;
            tmplongpath[lp++] = *p++;
        }
        for (; *p && *p != '/' && *p != '\\'; p++);
        tmplen = p - (shortpath + sp);
        lstrcpynW(tmplongpath + lp, shortpath + sp, tmplen + 1);
        /* Check if the file exists and use the existing file name */
        goit = FindFirstFileW(tmplongpath, &wfd);
        if (goit == INVALID_HANDLE_VALUE)
        {
            DPRINT("not found %s!\n", tmplongpath);
            SetLastError ( ERROR_FILE_NOT_FOUND );
            return 0;
        }
        FindClose(goit);
        wcscpy(tmplongpath + lp, wfd.cFileName);
        lp += wcslen(tmplongpath + lp);
        sp += tmplen;
    }
    tmplen = wcslen(shortpath) - 1;
    if ((shortpath[tmplen] == '/' || shortpath[tmplen] == '\\') &&
        (tmplongpath[lp - 1] != '/' && tmplongpath[lp - 1] != '\\'))
        tmplongpath[lp++] = shortpath[tmplen];
    tmplongpath[lp] = 0;

    tmplen = wcslen(tmplongpath) + 1;
    if (tmplen <= longlen)
    {
        wcscpy(longpath, tmplongpath);
        DPRINT("returning %s\n", longpath);
        tmplen--; /* length without 0 */
    }

    return tmplen;
}



/***********************************************************************
 *           GetLongPathNameA   (KERNEL32.@)
 */
DWORD STDCALL GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
{
    WCHAR *shortpathW;
    WCHAR longpathW[MAX_PATH];
    DWORD ret;

    DPRINT("GetLongPathNameA %s, %i\n",shortpath,longlen );

    if (!(shortpathW = FilenameA2W( shortpath, FALSE )))
      return 0;

    ret = GetLongPathNameW(shortpathW, longpathW, MAX_PATH);

    if (!ret) return 0;
    if (ret > MAX_PATH)
    {
        SetLastError(ERROR_FILENAME_EXCED_RANGE);
        return 0;
    }

    return FilenameW2A_FitOrFail(longpath, longlen, longpathW,  ret+1 );
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -