コード例 #1
0
ファイル: asmcache.c プロジェクト: GYGit/reactos
static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface,
                                                           DWORD dwFlags,
                                                           LPCWSTR pszAssemblyName,
                                                           ASSEMBLY_INFO *pAsmInfo)
{
    IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
    IAssemblyName *asmname, *next = NULL;
    IAssemblyEnum *asmenum = NULL;
    HRESULT hr;

    TRACE("(%p, %d, %s, %p)\n", iface, dwFlags,
          debugstr_w(pszAssemblyName), pAsmInfo);

    if (pAsmInfo)
    {
        if (pAsmInfo->cbAssemblyInfo == 0)
            pAsmInfo->cbAssemblyInfo = sizeof(ASSEMBLY_INFO);
        else if (pAsmInfo->cbAssemblyInfo != sizeof(ASSEMBLY_INFO))
            return E_INVALIDARG;
    }

    hr = CreateAssemblyNameObject(&asmname, pszAssemblyName,
                                  CANOF_PARSE_DISPLAY_NAME, NULL);
    if (FAILED(hr))
        return hr;

    cache_lock( cache );

    hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
    if (FAILED(hr))
        goto done;

    for (;;)
    {
        hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
        if (hr != S_OK)
        {
            hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
            goto done;
        }
        hr = IAssemblyName_IsEqual(asmname, next, ASM_CMPF_IL_ALL);
        if (hr == S_OK) break;
    }

    if (!pAsmInfo)
        goto done;

    hr = IAssemblyName_GetPath(next, pAsmInfo->pszCurrentAssemblyPathBuf, &pAsmInfo->cchBuf);

    pAsmInfo->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED;

done:
    IAssemblyName_Release(asmname);
    if (next) IAssemblyName_Release(next);
    if (asmenum) IAssemblyEnum_Release(asmenum);
    cache_unlock( cache );
    return hr;
}
コード例 #2
0
ファイル: asmcache.c プロジェクト: GYGit/reactos
static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface,
                                                           DWORD dwFlags,
                                                           LPCWSTR pszAssemblyName,
                                                           LPCFUSION_INSTALL_REFERENCE pRefData,
                                                           ULONG *pulDisposition)
{
    HRESULT hr;
    IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
    IAssemblyName *asmname, *next = NULL;
    IAssemblyEnum *asmenum = NULL;
    WCHAR *p, *path = NULL;
    ULONG disp;
    DWORD len;

    TRACE("(%p, 0%08x, %s, %p, %p)\n", iface, dwFlags,
          debugstr_w(pszAssemblyName), pRefData, pulDisposition);

    if (pRefData)
    {
        FIXME("application reference not supported\n");
        return E_NOTIMPL;
    }
    hr = CreateAssemblyNameObject( &asmname, pszAssemblyName, CANOF_PARSE_DISPLAY_NAME, NULL );
    if (FAILED( hr ))
        return hr;

    cache_lock( cache );

    hr = CreateAssemblyEnum( &asmenum, NULL, asmname, ASM_CACHE_GAC, NULL );
    if (FAILED( hr ))
        goto done;

    hr = IAssemblyEnum_GetNextAssembly( asmenum, NULL, &next, 0 );
    if (hr == S_FALSE)
    {
        if (pulDisposition)
            *pulDisposition = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED;
        goto done;
    }
    hr = IAssemblyName_GetPath( next, NULL, &len );
    if (hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ))
        goto done;

    if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }
    hr = IAssemblyName_GetPath( next, path, &len );
    if (FAILED( hr ))
        goto done;

    if (DeleteFileW( path ))
    {
        if ((p = strrchrW( path, '\\' )))
        {
            *p = 0;
            RemoveDirectoryW( path );
            if ((p = strrchrW( path, '\\' )))
            {
                *p = 0;
                RemoveDirectoryW( path );
            }
        }
        disp = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED;
        hr = S_OK;
    }
    else
    {
        disp = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED;
        hr = S_FALSE;
    }
    if (pulDisposition) *pulDisposition = disp;

done:
    IAssemblyName_Release( asmname );
    if (next) IAssemblyName_Release( next );
    if (asmenum) IAssemblyEnum_Release( asmenum );
    HeapFree( GetProcessHeap(), 0, path );
    cache_unlock( cache );
    return hr;
}
コード例 #3
0
void    AsmMan::EndAssembly()
{
    if(m_pCurAsmRef)
    {
        if(m_pCurAsmRef->isRef)
        { // list the assembly ref
            if(GetAsmRefByName(m_pCurAsmRef->szAlias))
            {
                //report->warn("Multiple declarations of Assembly Ref '%s', ignored except the 1st one\n",m_pCurAsmRef->szName);
                delete m_pCurAsmRef;
                m_pCurAsmRef = NULL;
                return;
            }
            if(m_pCurAsmRef->isAutodetect)
            {
                IAssemblyName* pIAsmName;
                HRESULT hr;
                // Convert name to Unicode
                WszMultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf);
                hr = CreateAssemblyNameObject(&pIAsmName,wzUniBuf,CANOF_PARSE_DISPLAY_NAME,NULL);
                if(SUCCEEDED(hr))
                {
                    // set enumeration criteria: what is known about AsmRef (besides name)
                    if(m_pCurAsmRef->usVerMajor != (USHORT)0xFFFF)
                        pIAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,&(m_pCurAsmRef->usVerMajor),2);
                    if(m_pCurAsmRef->usVerMinor != (USHORT)0xFFFF)
                        pIAsmName->SetProperty(ASM_NAME_MINOR_VERSION,&(m_pCurAsmRef->usVerMinor),2);
                    if(m_pCurAsmRef->usBuild != (USHORT)0xFFFF)
                        pIAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,&(m_pCurAsmRef->usBuild),2);
                    if(m_pCurAsmRef->usRevision != (USHORT)0xFFFF)
                        pIAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,&(m_pCurAsmRef->usRevision),2);
                    if(m_pCurAsmRef->pPublicKeyToken)
                        pIAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
                                               m_pCurAsmRef->pPublicKeyToken->ptr(),
                                               m_pCurAsmRef->pPublicKeyToken->length());
                    if(m_pCurAsmRef->pLocale)
                        pIAsmName->SetProperty(ASM_NAME_CULTURE,
                                               m_pCurAsmRef->pLocale->ptr(),
                                               m_pCurAsmRef->pLocale->length());

                    // enumerate assemblies
                    IAssemblyEnum* pIAsmEnum = NULL;
                    hr = CreateAssemblyEnum(&pIAsmEnum, NULL, pIAsmName, ASM_CACHE_GAC, NULL);
                    if(SUCCEEDED(hr))
                    {
                        IAssemblyName* pIAsmNameFound;
                        IAssemblyName* pIAsmNameLatestVer = NULL;
                        ULONGLONG   ullVer=0, ullVerLatest=0;
                        DWORD  dwVerHi, dwVerLo;
    
                        // find the latest and greatest, if any
                        for(;;)
                        {
                            pIAsmNameFound = NULL;
                            hr = pIAsmEnum->GetNextAssembly(NULL,&pIAsmNameFound,0); 
                            if(SUCCEEDED(hr) && pIAsmNameFound)
                            {
    
                                pIAsmNameFound->GetVersion(&dwVerHi,&dwVerLo);
                                ullVer = (ULONGLONG)dwVerHi;
                                ullVer <<= sizeof(DWORD);
                                ullVer |= dwVerLo;
                                if(ullVer > ullVerLatest)
                                {
                                    if(pIAsmNameLatestVer)
                                       pIAsmNameLatestVer->Release(); 
                                    ullVerLatest = ullVer;
                                    pIAsmNameLatestVer = pIAsmNameFound;
                                }
                                else
                                    pIAsmNameFound->Release();
                            }
                            else break;
                        }
                        // if found, fill the gaps
                        if(pIAsmNameLatestVer)
                        {
                            DWORD cbSize=0;
                            USHORT usDummy=0;

                            if(m_pCurAsmRef->pPublicKeyToken == NULL)
                            {
                                cbSize = 1024;
                                pIAsmNameLatestVer->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
                                                wzUniBuf, &cbSize);
                                if(cbSize)
                                {
                                    if((m_pCurAsmRef->pPublicKeyToken = new BinStr()))
                                        memcpy(m_pCurAsmRef->pPublicKeyToken->getBuff(cbSize),
                                            wzUniBuf, cbSize);
                                }
                            }
    
                            if(m_pCurAsmRef->usVerMajor == (USHORT)0xFFFF)
                            {
                                cbSize = (DWORD)sizeof(WORD);
                                pIAsmNameLatestVer->GetProperty(ASM_NAME_MAJOR_VERSION,
                                                &usDummy, &cbSize);
                                m_pCurAsmRef->usVerMajor = usDummy;
                            }
                            if(m_pCurAsmRef->usVerMinor == (USHORT)0xFFFF)
                            {
                                cbSize = (DWORD)sizeof(WORD);
                                pIAsmNameLatestVer->GetProperty(ASM_NAME_MINOR_VERSION,
                                                &usDummy, &cbSize);
                                m_pCurAsmRef->usVerMinor = usDummy;
                            }
                            if(m_pCurAsmRef->usBuild == (USHORT)0xFFFF)
                            {
                                cbSize = (DWORD)sizeof(WORD);
                                pIAsmNameLatestVer->GetProperty(ASM_NAME_BUILD_NUMBER,
                                                &usDummy, &cbSize);
                                m_pCurAsmRef->usBuild = usDummy;
                            }
                            if(m_pCurAsmRef->usRevision == (USHORT)0xFFFF)
                            {
                                cbSize = (DWORD)sizeof(WORD);
                                pIAsmNameLatestVer->GetProperty(ASM_NAME_REVISION_NUMBER,
                                                &usDummy, &cbSize);
                                m_pCurAsmRef->usRevision = usDummy;
                            }
                            
                            if(m_pCurAsmRef->pLocale == NULL)
                            {
                                cbSize = 1024;
                                pIAsmNameLatestVer->GetProperty(ASM_NAME_CULTURE,
                                                wzUniBuf, &cbSize);

                                if(cbSize > (DWORD)sizeof(WCHAR))
                                {
                                    if((m_pCurAsmRef->pLocale = new BinStr()))
                                        memcpy(m_pCurAsmRef->pLocale->getBuff(cbSize),
                                            wzUniBuf, cbSize);
                                }
                            }
                            pIAsmNameLatestVer->Release(); 
                        }
                        else
                            report->warn("Failed to autodetect assembly '%s'\n",m_pCurAsmRef->szName);
                        // if no assembly found, leave it as is, it might be not a GAC assembly
    
                        pIAsmEnum->Release();
                    }
                    else
                        report->error("Failed to enum assemblies %S, hr=0x%08X\n",wzUniBuf,hr);
                    pIAsmName->Release();
                }
                else
                    report->error("Failed to create assembly name object for %S, hr=0x%08X\n",wzUniBuf,hr);
            } // end if isAutodetect
            m_AsmRefLst.PUSH(m_pCurAsmRef);
            m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef);
        }
        else
        {
            HRESULT                 hr = S_OK;
            m_pCurAsmRef->tkTok = TokenFromRid(1,mdtAssembly);
            // Determine the strong name public key. This may have been set
            // via a directive in the source or from the command line (which
            // overrides the directive). From the command line we may have
            // been provided with a file or the name of a CAPI key
            // container. Either may contain a public key or a full key
            // pair.
            if (((Assembler*)m_pAssembler)->m_wzKeySourceName)
            {
                {
                    // Read public key or key pair from file.
                    HANDLE hFile = WszCreateFile(((Assembler*)m_pAssembler)->m_wzKeySourceName,
                                                 GENERIC_READ,
                                                 FILE_SHARE_READ,
                                                 NULL,
                                                 OPEN_EXISTING,
                                                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
                                                 NULL);
                    if(hFile == INVALID_HANDLE_VALUE)
                    {
                        hr = GetLastError();
                        report->error("Failed to open key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr);
                        m_pCurAsmRef = NULL;
                        return;
                    }

                    // Determine file size and allocate an appropriate buffer.
                    m_sStrongName.m_cbPublicKey = SafeGetFileSize(hFile, NULL);
                    if (m_sStrongName.m_cbPublicKey == 0xffffffff) {
                        report->error("File size too large\n");
                        m_pCurAsmRef = NULL;
                        CloseHandle(hFile);
                        return;
                    }

                    m_sStrongName.m_pbPublicKey = new BYTE[m_sStrongName.m_cbPublicKey];
                    if (m_sStrongName.m_pbPublicKey == NULL) {
                        report->error("Failed to allocate key buffer\n");
                        m_pCurAsmRef = NULL;
                        CloseHandle(hFile);
                        return;
                    }
                    m_sStrongName.m_dwPublicKeyAllocated = 2;

                    // Read the file into the buffer.
                    DWORD dwBytesRead;
                    if (!ReadFile(hFile, m_sStrongName.m_pbPublicKey, m_sStrongName.m_cbPublicKey, &dwBytesRead, NULL)) {
                        hr = GetLastError();
                        report->error("Failed to read key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr);
                        m_pCurAsmRef = NULL;
                        CloseHandle(hFile);
                        return;
                    }

                    CloseHandle(hFile);

                    // Guess whether we're full or delay signing based on
                    // whether the blob passed to us looks like a public
                    // key. (I.e. we may just have copied a full key pair
                    // into the public key buffer).
                    if (m_sStrongName.m_cbPublicKey >= sizeof(PublicKeyBlob) &&
                        (offsetof(PublicKeyBlob, PublicKey) +
                         ((PublicKeyBlob*)m_sStrongName.m_pbPublicKey)->cbPublicKey) == m_sStrongName.m_cbPublicKey)
                        m_sStrongName.m_fFullSign = FALSE;
                    else
                        m_sStrongName.m_fFullSign = TRUE;

                    // If we really have a key pair, we'll move it into a
                    // key container so the signing code gets the key pair
                    // from a consistent place.
                    if (m_sStrongName.m_fFullSign)
                    {
                        m_sStrongName.m_pbPrivateKey = m_sStrongName.m_pbPublicKey;
                        m_sStrongName.m_cbPrivateKey = m_sStrongName.m_cbPublicKey;

                        m_sStrongName.m_pbPublicKey = NULL;
                        m_sStrongName.m_cbPublicKey = NULL;
                        m_sStrongName.m_dwPublicKeyAllocated = 0;

                        // Retrieve the public key portion as a byte blob.
                        if (!StrongNameGetPublicKey(NULL,
                                                    m_sStrongName.m_pbPrivateKey,
                                                    m_sStrongName.m_cbPrivateKey,
                                                    &m_sStrongName.m_pbPublicKey,
                                                    &m_sStrongName.m_cbPublicKey))
                        {
                            hr = StrongNameErrorInfo();
                            report->error("Failed to extract public key: 0x%08X\n",hr);
                            m_pCurAsmRef = NULL;
                            return;
                        }
    
                        m_sStrongName.m_dwPublicKeyAllocated = 2;
                    }
                }
            }
            else if (m_pAssembly->pPublicKey)
            {
                m_sStrongName.m_pbPublicKey = m_pAssembly->pPublicKey->ptr();
                m_sStrongName.m_cbPublicKey = m_pAssembly->pPublicKey->length();
                m_sStrongName.m_wzKeyContainer = NULL;
                m_sStrongName.m_fFullSign = FALSE;
                m_sStrongName.m_dwPublicKeyAllocated = 0;
            }
            else
            {
                m_sStrongName.m_pbPublicKey = NULL;
                m_sStrongName.m_cbPublicKey = 0;
                m_sStrongName.m_wzKeyContainer = NULL;
                m_sStrongName.m_fFullSign = FALSE;
                m_sStrongName.m_dwPublicKeyAllocated = 0;
            }

        }
        m_pCurAsmRef = NULL;
    }
    ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP();
}