how to use ICLRStrongName in .NET 4? - .net-4.0

Related to my previous posts I'm moving to .NET 4. I've found that using the previous StrongName.h to get my assembly signing key in unmanaged code is now deprecated, and I need to use MetaHost.h and ICLRStrongName::StrongNameTokenFromAssembly.
The previous StrongNameTokenFromAssembly(..) was very straight forward, now this new one has no documentation on how to use. Does anyone have experience with this interface?

Wow... that required a lot of hacking around. Here we go!
ICLRMetaHost *pMetaHost = NULL;
HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost,
IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
if(hr == S_OK)
{
WCHAR version[100];
DWORD size;
hr == pMetaHost->GetVersionFromFile(MyGetApplicationExecutablePath().c_str(), (LPWSTR) &version, &size);
if(hr == S_OK)
{
LPWSTR assemblyVer = version;
ICLRRuntimeInfo *pRuntimInfo = NULL;
hr = pMetaHost->GetRuntime(assemblyVer, IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimInfo);
if (hr == S_OK)
{
ICLRStrongName *pStrongName = NULL;
hr = pRuntimInfo->GetInterface(CLSID_CLRStrongName, IID_ICLRStrongName, (LPVOID*)&pStrongName);
if(hr == S_OK)
{
pStrongName->StrongNameTokenFromAssembly(MyGetApplicationExecutablePath().c_str(), &token, &len);
DWORD verified = 0;
BOOLEAN sigVerified = pStrongName->StrongNameSignatureVerification(MyGetApplicationExecutablePath().c_str(), SN_INFLAG_FORCE_VER , &verified);
if (!verified)
{
//Do something nasty here if the Signature verification failed
}
pStrongName->StrongNameFreeBuffer(token);
}
}
}
}

Related

Quick Access and Namespace Extensions: Unpin object

When I right click on an lnk file - link on a virtual folder in a namespace extension -, then the functions CreateViewObject and/or GetUiObjectOf of my IShellFolder/IShellFolder2 implementations are called. These functions are called with the IID_IContextMenu as parameter (riid). Also when QueryContextMenu is called the flag CMF_VERBSONLY (0x00000002) is set. It means that 1) I know that a menu should be shown and 2) that because of the flag CMF_VERBSONLY that this menu was queried by a .lnk file and that (source Microsoft):
0x00000002. The shortcut menu is that of a shortcut file (normally, a
.lnk file). Shortcut menu handlers should ignore this value.
Most of the time I don't add menu items when this flag is present. When right-clicking on an .lnk file then windows will return a standard menu for .lnk files and the opportunity will be offered to delete this file. I had the same opportunity with the favorites folder on Windows 7. Since Windows 10 and "introduction" of quick access it is not possible anymore. No "Unpin" menu item will be shown by default.
Since it's very difficult from the namespace extension, assuming IID_IContextMenu and CMF_VERBSONLY to know if the object is pinned in quick access and also how to unpin it - I probably would have to open the automatic jump lists folder and then check all the jump list files against my object displayname - , I was wondering if there is an easier way to handle this (at the end jump list are a concatenation of lnk files).
Thanks for your help
Thanks to Simon Mourier's hint, here a possible way to check if a folder (of any type) is pinned in quick access or not...
extern bool __cdecl IsInQuickAccess(LPWSTR folderParsingName)
{
IShellFolder* desktopFolder;
HRESULT hr = SHGetDesktopFolder(&desktopFolder);
bool isInQuickAccess = false;
if (SUCCEEDED(hr))
{
LPITEMIDLIST quickAccessIdList;
hr = desktopFolder->ParseDisplayName(NULL, NULL, _T("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}"), NULL, &quickAccessIdList, NULL);
if (SUCCEEDED(hr))
{
IShellFolder* quickAccessFolder;
hr = desktopFolder->BindToObject(quickAccessIdList, NULL, IID_PPV_ARGS(&quickAccessFolder));
if (SUCCEEDED(hr))
{
IEnumIDList* currentChildren = NULL;
hr = quickAccessFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &currentChildren);
if (SUCCEEDED(hr))
{
CString wPathToFolder = CharLower(folderParsingName);
LPITEMIDLIST childPidl = NULL;
while (!isInQuickAccess && currentChildren->Next(1, &childPidl, NULL) == S_OK)
{
STRRET childDisplayName;
hr = quickAccessFolder->GetDisplayNameOf(childPidl, SHGDN_FORPARSING, &childDisplayName);
if (SUCCEEDED(hr))
{
LPWSTR childDisplayNameString;
hr = StrRetToStr(&childDisplayName, NULL, &childDisplayNameString);
if (SUCCEEDED(hr))
{
LPWSTR childDisplayNameStringToLower = CharLower(childDisplayNameString);
if (wPathToFolder.Compare(childDisplayNameStringToLower) == 0)
isInQuickAccess = true;
CoTaskMemFree(childDisplayNameString);
}
}
}
CoTaskMemFree(childPidl);
currentChildren->Release();
}
quickAccessFolder->Release();
}
CoTaskMemFree(quickAccessIdList);
}
desktopFolder->Release();
}
return isInQuickAccess;
}
and here unpin from home (with check if folder with given display name is in quick access).
extern void __cdecl UnpinFromHome(LPWSTR folderParsingName)
{
IShellFolder* desktopFolder;
HRESULT hr = SHGetDesktopFolder(&desktopFolder);
if (SUCCEEDED(hr))
{
LPITEMIDLIST quickAccessIdList;
hr = desktopFolder->ParseDisplayName(NULL, NULL, _T("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}"), NULL, &quickAccessIdList, NULL);
if (SUCCEEDED(hr))
{
IShellFolder* quickAccessFolder;
hr = desktopFolder->BindToObject(quickAccessIdList, NULL, IID_PPV_ARGS(&quickAccessFolder));
if (SUCCEEDED(hr))
{
IEnumIDList* currentChildren = NULL;
hr = quickAccessFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &currentChildren);
if (SUCCEEDED(hr))
{
CString wPathToFolder = CharLower(folderParsingName);
LPITEMIDLIST childPidl = NULL;
bool isInQuickAccess = false;
while (!isInQuickAccess && currentChildren->Next(1, &childPidl, NULL) == S_OK)
{
STRRET childDisplayName;
hr = quickAccessFolder->GetDisplayNameOf(childPidl, SHGDN_FORPARSING, &childDisplayName);
if (SUCCEEDED(hr))
{
LPWSTR childDisplayNameString;
hr = StrRetToStr(&childDisplayName, NULL, &childDisplayNameString);
if (SUCCEEDED(hr))
{
LPWSTR childDisplayNameStringToLower = CharLower(childDisplayNameString);
if (wPathToFolder.Compare(childDisplayNameStringToLower) == 0)
{
IContextMenu* childContextMenu;
LPCITEMIDLIST childCPidl = childPidl;
hr = quickAccessFolder->GetUIObjectOf(NULL, 1, &childCPidl, IID_IContextMenu, NULL, (void**)&childContextMenu);
if (SUCCEEDED(hr))
{
HMENU hmenu = CreatePopupMenu();
if (hmenu)
{
hr = childContextMenu->QueryContextMenu(hmenu, 0, 1, 0x7FFF, CMF_NORMAL);
if (SUCCEEDED(hr))
{
CMINVOKECOMMANDINFO info = { 0 };
info.cbSize = sizeof(info);
info.hwnd = NULL;
info.lpVerb = "unpinfromhome";
info.nShow = 1;
info.fMask = CMIC_MASK_ASYNCOK;
childContextMenu->InvokeCommand(&info);
}
DestroyMenu(hmenu);
}
}
isInQuickAccess = true;
}
CoTaskMemFree(childDisplayNameString);
}
}
}
CoTaskMemFree(childPidl);
currentChildren->Release();
}
quickAccessFolder->Release();
}
CoTaskMemFree(quickAccessIdList);
}
desktopFolder->Release();
}
}

DirectShow cannot detect PS3eye

I'm trying to use a PS3eye camera on Windows 10 with DirectShow sdk.
I've installed the driver and tested in AMCap that the PS3eye is working.
When in VS 2015, I defined a CCameraDS class with a function called CameraCount(), but when I call this function it always returns me 1 which represents the EasyCamera of my laptop. Am I missing something?
int CCameraDS::CameraCount()
{
int count = 0;
CoInitialize(NULL);
// enumerate all video capture devices
ICreateDevEnum *pCreateDevEnum = 0;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
IEnumMoniker *pEm = 0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR)
{
return count;
}
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
count++;
}
pCreateDevEnum = NULL;
pEm = NULL;
return count;
}
To verify, I have another method called CameraName(),
int CCameraDS::CameraName(int nCamID, char* sName, int nBufferSize)
{
int count = 0;
CoInitialize(NULL);
// enumerate all video capture devices
ICreateDevEnum *pCreateDevEnum = 0;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
IEnumMoniker *pEm = 0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR) return 0;
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
if (count == nCamID)
{
IPropertyBag *pBag=0;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if(hr == NOERROR)
{
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,sName, nBufferSize ,"",NULL);
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
break;
}
count++;
}
pCreateDevEnum = NULL;
pEm = NULL;
return 1;
}
When I input 0, I have EasyCamera returned, but input 1 with nothing output. Where is the problem?
Problem solved.
In fact, the PS3eye driver as well as AMCap software are both compiled under x86 environment, since I used x64 environment, the driver wasn't working I think.
I didn't expect this to be the solution but it does solve the problem.

Getting ICLRRuntimeInfo instance is null C++

I'm getting ICLRRuntimeInfo instance is null C++
DWORD pid = 2076;
HRESULT hr;
HANDLE hProcess;
ICLRMetaHost *pMetaHost = NULL;
IEnumUnknown *ppEnumerator = NULL;
ICLRRuntimeInfo *CLRRuntimeInfo = NULL;
ULONG pFetched = 0;
DWORD versionLength;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL) {
printf("process unable to open");
return 0;
}
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,*)&pMetaHost);
pMetaHost->EnumerateLoadedRuntimes(hProcess, &ppEnumerator);
if (ppEnumerator == 0) {
return 0;
}
hr = ppEnumerator->Next(1, (IUnknown **)&CLRRuntimeInfo, &pFetched);
if (hr == S_FALSE) {
printError(TEXT("CLRRuntimeInfo"));
return 0;
}
When I tried with EnumerateInstalledRuntimes, got all installed Runtimes
pMetaHost->EnumerateInstalledRuntimes( &ppEnumerator)
Windows error i got :failed with error 18 (There are no more files)
In Project properties -> VC++ Directories -> Library Dirctories-> $(NETFXKitsDir)Lib\um\x86
But I'm building solution with x64. Now changed to x86. working fine.

Wix Bootstrapper - download bundle packages from a secured http repository

I'm working on a burn bootstrapper that needs to download prerequisites from a http repository that require authentication.
So, how I should handle this request?
Thanks!
Got it! This can be achieved on OnResolveSource() event:
// variable used for authentication
static const LPCWSTR WIXSTDBA_VARIABLE_HTTP_DOWNLOAD_USER = L"HTTPDownloadUserName";
static const LPCWSTR WIXSTDBA_VARIABLE_HTTP_DOWNLOAD_PASS = L"HTTPDownloadPassword";
virtual STDMETHODIMP_(int) OnResolveSource(
__in_z LPCWSTR wzPackageOrContainerId,
__in_z_opt LPCWSTR wzPayloadId,
__in_z LPCWSTR wzLocalSource,
__in_z_opt LPCWSTR wzDownloadSource
)
{
int nResult = IDERROR; // assume we won't resolve source and that is unexpected.
LPWSTR sczHTTPDwnUserName = NULL;
LPWSTR sczHTTPDwnPassword = NULL;
BOOL bUseHTTPAuth = FALSE;
if (BalStringVariableExists(WIXSTDBA_VARIABLE_HTTP_DOWNLOAD_USER))
{
HRESULT hrUsr = BalGetStringVariable(WIXSTDBA_VARIABLE_HTTP_DOWNLOAD_USER, &sczHTTPDwnUserName);
HRESULT hrPwd = BalGetStringVariable(WIXSTDBA_VARIABLE_HTTP_DOWNLOAD_PASS, &sczHTTPDwnPassword);
if (SUCCEEDED(hrUsr) && SUCCEEDED(hrPwd)) bUseHTTPAuth = TRUE;
}
if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display)
{
if (wzDownloadSource)
{
if (bUseHTTPAuth)
{
HRESULT hr = m_pEngine->SetDownloadSource(wzPackageOrContainerId, wzPayloadId, wzDownloadSource, sczHTTPDwnUserName, sczHTTPDwnPassword);
nResult = SUCCEEDED(hr) ? IDDOWNLOAD : IDERROR;
}
else
nResult = IDDOWNLOAD;
}
else // prompt to change the source location.
{
// related stuff
}
}
else if (wzDownloadSource)
{
// If doing a non-interactive install and download source is available, let's try downloading the package silently
if (bUseHTTPAuth)
{
HRESULT hr = m_pEngine->SetDownloadSource(wzPackageOrContainerId, wzPayloadId, wzDownloadSource, sczHTTPDwnUserName, sczHTTPDwnPassword);
nResult = SUCCEEDED(hr) ? IDRETRY : IDERROR;
}
else
nResult = IDDOWNLOAD;
}
// else there's nothing more we can do in non-interactive mode
return CheckCanceled() ? IDCANCEL : nResult;
}

Getting a IRandomAccessStream to a file in Windows Store App

I need to get IRandomAccessStream to a file without a picker.
However, I'm stuck with IStorageFile or IRandomAccessStreamReference and can't find a way to get IRandomAccessStream from either of those.
I write the code with C++ (no /ZW), but I don't think it matters in this case.
Please help,
Moshe
I managed to do what I wanted using OpenReadAsync of StorageFile. But this involves 2 async calls and is cumbersome. I wonder if there is a shorter and a more elegant way. The relevant sample code below:
IFACEMETHODIMP MyClass::BeginCreateObject(
//... rest of parameters
_In_ IMFAsyncCallback *pCallback,
_In_ IUnknown *punkState)
{
OutputDebugStringW(__FUNCTIONW__);
HRESULT hr;
HString hstrStorageFile;
hstrStorageFile.Set(RuntimeClass_Windows_Storage_StorageFile);
// Get the Activation Factory
ComPtr<IActivationFactory> pStorageFileActivationFactory;
hr = GetActivationFactory(hstrStorageFile.Get(), &pStorageFileActivationFactory);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
// QI for StorageFileStatics
ComPtr<IStorageFileStatics> pStorageFileStatics;
hr = pStorageFileActivationFactory.As(&pStorageFileStatics);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
HString hstrFileName;
hstrFileName.Set(L"My_Cool_Movie.ts");
// Call CreateFileAsync
__FIAsyncOperation_1_Windows__CStorage__CStorageFile * operation;
hr = pStorageFileStatics->GetFileFromPathAsync(hstrFileName.Get(),
&operation
);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
typedef IAsyncOperationCompletedHandler<StorageFile*> HandlerDoneType;
ComPtr<HandlerDoneType> handler(Callback<HandlerDoneType>(
this, &MyClass::FileOpenCompletionHandler));
hr = operation->put_Completed(handler.Get());
ComPtr<IMFAsyncResult> spResult;
//maybe I should pass some data in the first parameter?
hr = MFCreateAsyncResult(nullptr, pCallback, punkState, &_spOpenResult);
//the further processing will be done in the completion handler
return hr;
}
IFACEMETHODIMP MyClass::EndCreateObject(
_In_ IMFAsyncResult *pResult,
_Out_ MF_OBJECT_TYPE *pObjectType,
_Out_ IUnknown **ppObject)
{
OutputDebugStringW(__FUNCTIONW__);
if (pResult == nullptr || pObjectType == nullptr || ppObject == nullptr)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
//get a random access stream
if(!_spFile)
{
return E_FAIL;
}
ComPtr<IRandomAccessStream> streamHandle;
hr = _spStream.As(&streamHandle);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
//Do what you need with IRandomAccessStream!
//...
return S_OK;
}
IFACEMETHODIMP MyClass::CancelObjectCreation(
_In_ IUnknown *pIUnknownCancelCookie)
{
return E_NOTIMPL;
}
HRESULT MyClass::FileOpenCompletionHandler( IAsyncOperation<StorageFile*>* async, AsyncStatus status)
{
//file is open, call the invoke to carry one
if (status == Completed) {
HRESULT hr = async->GetResults(_spFile.GetAddressOf());
if (_spFile) {
ComPtr<IRandomAccessStreamReference> streamReference;
hr = _spFile.As(&streamReference);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
__FIAsyncOperation_1_Windows__CStorage__CStreams__CIRandomAccessStreamWithContentType * operation;
hr = streamReference->OpenReadAsync(&operation);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
typedef IAsyncOperationCompletedHandler<IRandomAccessStreamWithContentType*> OpenReadAsyncHandlerDoneType;
ComPtr<OpenReadAsyncHandlerDoneType> handler(Callback<OpenReadAsyncHandlerDoneType>(
this, &MyClass::FileOpenReadCompletionHandler));
hr = operation->put_Completed(handler.Get());
}
return hr;
}
else {
OutputDebugStringW(L"Unexpected async status\n");
return E_FAIL;
}
return S_OK;
}
HRESULT MyClass::FileOpenReadCompletionHandler( IAsyncOperation<IRandomAccessStreamWithContentType*>* async, AsyncStatus status)
{
if (status == Completed) {
HRESULT hr = async->GetResults(_spStream.GetAddressOf());
if (_spStream) {
_spOpenResult->SetStatus(S_OK);
hr = MFInvokeCallback(_spOpenResult.Get());
_spOpenResult.ReleaseAndGetAddressOf();
}
return hr;
}
else {
OutputDebugStringW(L"Unexpected async status\n");
return E_FAIL;
}
return S_OK;
}