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

📄 pidl.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
}

BOOL _ILIsValue(LPCITEMIDLIST pidl)
{
    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);

    TRACE("(%p)\n",pidl);

    return (pidl && lpPData && PT_VALUE == lpPData->type);
}

BOOL _ILIsCPanelStruct(LPCITEMIDLIST pidl)
{
    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);

    TRACE("(%p)\n",pidl);

    return (pidl && lpPData && (lpPData->type == 0));
}

/**************************************************************************
 *    _ILIsPidlSimple
 */
BOOL _ILIsPidlSimple(LPCITEMIDLIST pidl)
{
    BOOL ret = TRUE;

    if(! _ILIsDesktop(pidl))    /* pidl=NULL or mkid.cb=0 */
    {
        WORD len = pidl->mkid.cb;
        LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((const BYTE*)pidl) + len );

        if (pidlnext->mkid.cb)
            ret = FALSE;
    }

    TRACE("%s\n", ret ? "Yes" : "No");
    return ret;
}

/**************************************************************************
 *
 *    ### 3. section getting values from pidls ###
 */

 /**************************************************************************
 *  _ILSimpleGetText
 *
 * gets the text for the first item in the pidl (eg. simple pidl)
 *
 * returns the length of the string
 */
DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
{
    DWORD        dwReturn=0;
    LPSTR        szSrc;
    GUID const * riid;
    char szTemp[MAX_PATH];

    TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);

    if (!pidl)
        return 0;

    if (szOut)
        *szOut = 0;

    if (_ILIsDesktop(pidl))
    {
        /* desktop */
        if (HCR_GetClassNameA(&CLSID_ShellDesktop, szTemp, MAX_PATH))
        {
            if (szOut)
                lstrcpynA(szOut, szTemp, uOutSize);

            dwReturn = strlen (szTemp);
        }
    }
    else if (( szSrc = _ILGetTextPointer(pidl) ))
    {
        /* filesystem */
        if (szOut)
            lstrcpynA(szOut, szSrc, uOutSize);

        dwReturn = strlen(szSrc);
    }
    else if (( riid = _ILGetGUIDPointer(pidl) ))
    {
        /* special folder */
        if ( HCR_GetClassNameA(riid, szTemp, MAX_PATH) )
        {
            if (szOut)
                lstrcpynA(szOut, szTemp, uOutSize);

            dwReturn = strlen (szTemp);
        }
    }
    else
    {
        ERR("-- no text\n");
    }

    TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_a(szOut),dwReturn);
    return dwReturn;
}

 /**************************************************************************
 *  _ILSimpleGetTextW
 *
 * gets the text for the first item in the pidl (eg. simple pidl)
 *
 * returns the length of the string
 */
DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR szOut, UINT uOutSize)
{
    DWORD   dwReturn;
    char    szTemp[MAX_PATH];
    FileStructW *pFileStructW = _ILGetFileStructW(pidl);

    TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);

    if (pFileStructW) {
        lstrcpynW(szOut, pFileStructW->wszName, uOutSize);
        dwReturn = lstrlenW(pFileStructW->wszName);
    } else {
        dwReturn = _ILSimpleGetText(pidl, szTemp, MAX_PATH);

        if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, uOutSize))
            *szOut = 0;
    }

    TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_w(szOut),dwReturn);
    return dwReturn;
}

/**************************************************************************
 *
 *    ### 4. getting pointers to parts of pidls ###
 *
 **************************************************************************
 *  _ILGetDataPointer()
 */
LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
{
    if(pidl && pidl->mkid.cb != 0x00)
        return (LPPIDLDATA) &(pidl->mkid.abID);
    return NULL;
}

/**************************************************************************
 *  _ILGetTextPointer()
 * gets a pointer to the long filename string stored in the pidl
 */
LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl)
{
    /* TRACE(pidl,"(pidl%p)\n", pidl);*/

    LPPIDLDATA pdata = _ILGetDataPointer(pidl);

    if (!pdata)
        return NULL;

    switch (pdata->type)
    {
    case PT_GUID:
    case PT_SHELLEXT:
    case PT_YAGUID:
        return NULL;

    case PT_DRIVE:
    case PT_DRIVE1:
    case PT_DRIVE2:
    case PT_DRIVE3:
        return (LPSTR)&(pdata->u.drive.szDriveName);

    case PT_FOLDER:
    case PT_FOLDER1:
    case PT_VALUE:
    case PT_IESPECIAL1:
    case PT_IESPECIAL2:
        return (LPSTR)&(pdata->u.file.szNames);

    case PT_WORKGRP:
    case PT_COMP:
    case PT_NETWORK:
    case PT_NETPROVIDER:
    case PT_SHARE:
        return (LPSTR)&(pdata->u.network.szNames);
    }
    return NULL;
}

/**************************************************************************
 *  _ILGetSTextPointer()
 * gets a pointer to the short filename string stored in the pidl
 */
LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl)
{
    /* TRACE(pidl,"(pidl%p)\n", pidl); */

    LPPIDLDATA pdata =_ILGetDataPointer(pidl);

    if (!pdata)
        return NULL;

    switch (pdata->type)
    {
    case PT_FOLDER:
    case PT_VALUE:
    case PT_IESPECIAL1:
    case PT_IESPECIAL2:
        return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);

    case PT_WORKGRP:
        return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
    }
    return NULL;
}

/**************************************************************************
 * _ILGetGUIDPointer()
 *
 * returns reference to guid stored in some pidls
 */
IID* _ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
    LPPIDLDATA pdata =_ILGetDataPointer(pidl);

    TRACE("%p\n", pidl);

    if (!pdata)
        return NULL;

    TRACE("pdata->type 0x%04x\n", pdata->type);
    switch (pdata->type)
    {
    case PT_SHELLEXT:
    case PT_GUID:
    case PT_YAGUID:
        return &(pdata->u.guid.guid);

    default:
        TRACE("Unknown pidl type 0x%04x\n", pdata->type);
        break;
    }
    return NULL;
}

/******************************************************************************
 * _ILGetFileStructW [Internal]
 *
 * Get pointer the a SHITEMID's FileStructW field if present
 *
 * PARAMS
 *  pidl [I] The SHITEMID
 *
 * RETURNS
 *  Success: Pointer to pidl's FileStructW field.
 *  Failure: NULL
 */
FileStructW* _ILGetFileStructW(LPCITEMIDLIST pidl) {
    FileStructW *pFileStructW;
    WORD cbOffset;
    
    if (!(_ILIsValue(pidl) || _ILIsFolder(pidl)))
        return NULL;

    cbOffset = *(WORD*)((LPBYTE)pidl + pidl->mkid.cb - sizeof(WORD));
    pFileStructW = (FileStructW*)((LPBYTE)pidl + cbOffset);

    /* Currently I don't see a fool prove way to figure out if a pidl is for sure of WinXP
     * style with a FileStructW member. If we switch all our shellfolder-implementations to
     * the new format, this won't be a problem. For now, we do as many sanity checks as possible. */
    if (cbOffset & 0x1 || /* FileStructW member is word aligned in the pidl */
        /* FileStructW is positioned after FileStruct */
        cbOffset < sizeof(pidl->mkid.cb) + sizeof(PIDLTYPE) + sizeof(FileStruct) ||
        /* There has to be enough space at cbOffset in the pidl to hold FileStructW and cbOffset */
        cbOffset > pidl->mkid.cb - sizeof(cbOffset) - sizeof(FileStructW) ||
        pidl->mkid.cb != cbOffset + pFileStructW->cbLen)
    {
        WARN("Invalid pidl format (cbOffset = %d)!\n", cbOffset);
        return NULL;
    }

    return pFileStructW;
}

/*************************************************************************
 * _ILGetFileDateTime
 *
 * Given the ItemIdList, get the FileTime
 *
 * PARAMS
 *      pidl        [I] The ItemIDList
 *      pFt         [I] the resulted FILETIME of the file
 *
 * RETURNS
 *     True if Successful
 *
 * NOTES
 *
 */
BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *pFt)
{
    LPPIDLDATA pdata = _ILGetDataPointer(pidl);

    if (!pdata)
        return FALSE;

    switch (pdata->type)
    {
    case PT_FOLDER:
    case PT_VALUE:
        DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt);
        break;
    default:
        return FALSE;
    }
    return TRUE;
}

BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
    FILETIME ft,lft;
    SYSTEMTIME time;
    BOOL ret;

    if (_ILGetFileDateTime( pidl, &ft ))
    {
        FileTimeToLocalFileTime(&ft, &lft);
        FileTimeToSystemTime (&lft, &time);

        ret = GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  pOut, uOutSize);
        if (ret) 
        {
            /* Append space + time without seconds */
            pOut[ret-1] = ' ';
            GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, &pOut[ret], uOutSize - ret);
        }
    }
    else
    {
        pOut[0] = '\0';
        ret = FALSE;
    }
    return ret;
}

/*************************************************************************
 * _ILGetFileSize
 *
 * Given the ItemIdList, get the FileSize
 *
 * PARAMS
 *    pidl     [I] The ItemIDList
 *    pOut     [I] The buffer to save the result
 *    uOutsize [I] The size of the buffer
 *
 * RETURNS
 *    The FileSize
 *
 * NOTES
 *    pOut can be null when no string is needed
 *
 */
DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
    LPPIDLDATA pdata = _ILGetDataPointer(pidl);
    DWORD dwSize;

    if (!pdata)
        return 0;

    switch (pdata->type)
    {
    case PT_VALUE:
        dwSize = pdata->u.file.dwFileSize;
        if (pOut)
            StrFormatByteSizeA(dwSize, pOut, uOutSize);
        return dwSize;
    }
    if (pOut)
        *pOut = 0x00;
    return 0;
}

BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
    char szTemp[MAX_PATH];
    const char * pPoint;
    LPCITEMIDLIST  pidlTemp=pidl;

    TRACE("pidl=%p\n",pidl);

    if (!pidl)
        return FALSE;

    pidlTemp = ILFindLastID(pidl);

    if (!_ILIsValue(pidlTemp))
        return FALSE;
    if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH))
        return FALSE;

    pPoint = PathFindExtensionA(szTemp);

    if (!*pPoint)
        return FALSE;

    pPoint++;
    lstrcpynA(pOut, pPoint, uOutSize);
    TRACE("%s\n",pOut);

    return TRUE;
}

/*************************************************************************
 * _ILGetFileType
 *
 * Given the ItemIdList, get the file type description
 *
 * PARAMS
 *      pidl        [I] The ItemIDList (simple)
 *      pOut        [I] The buffer to save the result
 *      uOutsize    [I] The size of the buffer
 *
 * RETURNS
 *    nothing
 *
 * NOTES
 *    This function copies as much as possible into the buffer.
 */
void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
    if(_ILIsValue(pidl))
    {
        char sTemp[64];

        if(uOutSize > 0)
            pOut[0] = 0;
        if (_ILGetExtension (pidl, sTemp, 64))
        {
            if (!( HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE)
                && HCR_MapTypeToValueA(sTemp, pOut, uOutSize, FALSE )))
            {
                lstrcpynA (pOut, sTemp, uOutSize - 6);
                strcat (pOut, "-file");
            }
        }
    }
    else
        lstrcpynA(pOut, "Folder", uOutSize);
}

/*************************************************************************
 * _ILGetFileAttributes
 *
 * Given the ItemIdList, get the Attrib string format
 *
 * PARAMS
 *      pidl        [I] The ItemIDList
 *      pOut        [I] The buffer to save the result
 *      uOutsize    [I] The size of the Buffer
 *
 * RETURNS
 *     Attributes
 *
 * FIXME
 *  return value 0 in case of error is a valid return value
 *
 */
DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
    LPPIDLDATA pData = _ILGetDataPointer(pidl);
    WORD wAttrib = 0;
    int i;

    if (!pData)
        return 0;

    switch(pData->type)
    {
    case PT_FOLDER:
    case PT_VALUE:
        wAttrib = pData->u.file.uFileAttribs;
        break;
    }

    if(uOutSize >= 6)
    {
        i=0;
        if(wAttrib & FILE_ATTRIBUTE_READONLY)
            pOut[i++] = 'R';
        if(wAttrib & FILE_ATTRIBUTE_HIDDEN)
            pOut[i++] = 'H';
        if(wAttrib & FILE_ATTRIBUTE_SYSTEM)
            pOut[i++] = 'S';
        if(wAttrib & FILE_ATTRIBUTE_ARCHIVE)
            pOut[i++] = 'A';
        if(wAttrib & FILE_ATTRIBUTE_COMPRESSED)
            pOut[i++] = 'C';
        pOut[i] = 0x00;
    }
    return wAttrib;
}

/*************************************************************************
 * ILFreeaPidl
 *
 * free a aPidl struct
 */
void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl)
{
    UINT   i;

    if (apidl)
    {
        for (i = 0; i < cidl; i++)
            SHFree(apidl[i]);
        SHFree(apidl);
    }
}

/*************************************************************************
 * ILCopyaPidl
 *
 * copies an aPidl struct
 */
LPITEMIDLIST* _ILCopyaPidl(LPCITEMIDLIST * apidlsrc, UINT cidl)
{
    UINT i;
    LPITEMIDLIST *apidldest;

    apidldest = SHAlloc(cidl * sizeof(LPITEMIDLIST));
    if (!apidlsrc)
        return NULL;

    for (i = 0; i < cidl; i++)
        apidldest[i] = ILClone(apidlsrc[i]);

    return apidldest;
}

/*************************************************************************
 * _ILCopyCidaToaPidl
 *
 * creates aPidl from CIDA
 */
LPITEMIDLIST* _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida)
{
    UINT i;
    LPITEMIDLIST *dst;

    dst = SHAlloc(cida->cidl * sizeof(LPITEMIDLIST));
    if (!dst)
        return NULL;

    if (pidl)
        *pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[0]]));

    for (i = 0; i < cida->cidl; i++)
        dst[i] = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[i + 1]]));

    return dst;
}

⌨️ 快捷键说明

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