what does ID3D11DeviceChild::SetPrivateDataInterface usage? - windows

the function in this https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nn-d3d11-id3d11devicechild
this is useless code, dont see it, i just want to make this website happy
pContext->IAGetVertexBuffers(0, 1, &veBuffer, &Stride, &veBufferOffset);
if (veBuffer)
veBuffer->GetDesc(&vedesc);
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D11_USAGE_STAGING;
bufferDesc.ByteWidth = vedesc.ByteWidth;
bufferDesc.BindFlags = 0;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
bufferDesc.MiscFlags = 0;
ID3D11Device **pDeviceExtra = nullptr;
veBuffer->GetDevice(pDeviceExtra); //Can I use this to get to the device object?
//Create the buffer.
HRESULT hr = pDeviceExtra->CreateBuffer(&bufferDesc, NULL, &readVB);
assert(hr == S_OK);
pContext->CopyResource(readVB, veBuffer);
i know this function will set a iunknown interface to the device, but after that, how can i use this interface? what is this function mean?
i have try to search in web, but i cant find any anwser

This API is not for general consumption. It's there for internal reasons, and in normal Direct3D programming you will never use ID3D11DeviceChild::SetPrivateDataInterface. In almost all cases it's going to do nothing and return S_OK or do nothing and return E_NOTIMPL.
The ID3D11DeviceChild::SetPrivateData method can be used to provide debug name information for the debug layer:
static const char c_szName[] = "My name";
hr = pContext->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( c_szName ) - 1, c_szName );
Otherwise, you don't really need to use the ID3D11DeviceChild interface itself for anything. Having an interface derived from it is mostly an indication that it's lifetime is tied to the lifetime of it's owning ID3D11Device instance regardless of that object's refcount: see Microsoft Docs.

Related

Why WNetOpenEnum gets ERROR_INVALID_ADDRESS (487) result?

trying to rewrite using WINAPI library https://learn.microsoft.com/en-us/windows/win32/wnet/enumerating-network-resources on Rust
let dw_result: DWORD;
let mut h_enum: LPHANDLE = null_mut();
let mut lpnr_local: LPNETRESOURCEW = null_mut();
dw_result = WNetOpenEnumW(RESOURCE_GLOBALNET, // all network resources
RESOURCETYPE_ANY, // all resources
0, // enumerate all resources
lpnr_local, // NULL first time the function is called
h_enum);
if dw_result != WN_NO_ERROR {
println!("WnetOpenEnum failed with error {:?}\n", dw_result);
}
But this code assign 487 into dw_result which means ERROR_INVALID_ADDRESS
And I can't get what is wrong
I guess your doubt is the difference between LPHANDLE and HANDLE.
LP stands for Long Pointer. It's a pointer to a handle.
If you want to use LPHANDLE, please give it a legal address。
Like this:(C++)
HANDLE ph;
LPHANDLE hEnum = &ph;
Or simply use HANDLE.
let mut h_enum: HANDLE;
...
dw_result = WNetOpenEnumW(RESOURCE_GLOBALNET, // all network resources
RESOURCETYPE_ANY, // all resources
0, // enumerate all resources
lpnr_local, // NULL first time the function is called
&h_enum);
Related: LPHANDLE vs. HANDLE

Cannot access IBDA_DigitalDemodulator interface successfully though application on Win7

I need to build an application to configure some demodulator parameters(like Symbol rate, modulation type, etc), and I did these things through Microsoft BDA architecture;however, here is my code as below:
CComPtr <IBDA_Topology> pITopology;
CComPtr <IBDA_AutoDemodulate> m_pIAutoDemod;
CComPtr <IBDA_DigitalDemodulator> m_pIDigiDemod;
hr = m_pTunerDevice->QueryInterface(IID_IBDA_Topology,
reinterpret_cast<void**>(&pITopology) );
ULONG nNodesTypeNum = 0;
ULONG NodesType[10];
hr = pITopology->GetNodeTypes(&nNodesTypeNum, 10, NodesType);
CComPtr <IUnknown> pIUknow;
// NodesType[1] is the Demod node
hr = pITopology->GetControlNode(0, 1, NodesType[1], &pIUknow);
ULONG nInterfacesNum = 0;
GUID InterfacesGUID[10];
// After this call, we sure that InerfacesGUID[0] == IID_IBDA_AutoDemodulate
// and InerfacesGUID[1] == IID_IBDA_DigitalDemodulator
hr = pITopology->GetNodeInterfaces(NodesType[1], &nInterfacesNum, 10,
InerfacesGUID);
// Call this success
hr = pIUknow->QueryInterface(IID_IBDA_DigitalDemodulator, (void
**)&m_pIDigiDemod);
ModulationType type = BDA_MOD_NOT_DEFINED;
hr = m_pIDigiDemod->get_ModulationType(&type);//failed here
I can get the interface object with no problem; but when I call whatever methods(get modulation type, get symbol rate), it always returns E_HANDLE; and I also checks my BDA driver is good.
Any ideas to point me in the right direction are appreciated.

playing files after accepting them through open dialog box

I am a new member and joined this site after referring to it loads of times when i was stuck with some programming problems. I am trying to code a media player (Win32 SDK VC++ 6.0) for my college project and I am stuck. I have searched on various forums and msdn and finally landed on the function GetShortPathName which enables me to play through folders and files which have a whitespace in their names. I will paste the code here so it will be much more clearer as to what i am trying to do.
case IDM_FILE_OPEN :
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = "Media Files (All Supported Types)\0*.avi;*.mpg;*.mpeg;*.asf;*.wmv;*.mp2;*.mp3\0"
"Movie File (*.avi;*.mpg;*.mpeg)\0*.avi;*.mpg;*.mpeg\0"
"Windows Media File (*.asf;*.wmv)\0*.asf;*.wmv\0"
"Audio File (*.mp2;*.mp3)\0*.mp2;*.mp3\0"
"All Files(*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_CREATEPROMPT;
ofn.lpstrDefExt = "mp3";
if(GetOpenFileName(&ofn))
{
length = GetShortPathName(szFileName, NULL, 0);
buffer = (TCHAR *) malloc (sizeof(length));
length = GetShortPathName(szFileName, buffer, length);
for(i = 0 ; i < MAX_PATH ; i++)
{
if(buffer[i] == '\\')
buffer[i] = '/';
}
SendMessage(hList,LB_ADDSTRING,0,(LPARAM)buffer);
mciSendString("open buffer alias myFile", NULL, 0, NULL);
mciSendString("play buffer", NULL, 0, NULL);
}
return 0;
using the GetShortPathName function i get the path as : D:/Mp3z/DEEPBL~1/03SLEE~1.mp3
Putting this path directly in Play button case
mciSendString("open D:/Mp3jh/DEEPBL~1/03SLEE~1.mp3 alias myFile", NULL, 0, NULL);
mciSendString("play myFile", NULL, 0, NULL);
the file opens and plays fine. But as soon as i try to open and play it through the open file dialog box, nothing happens. Any input appreciated.
It looks like the problem is that you're passing the name of the buffer variable to the mciSendString function as a string, rather than passing the contents of the buffer.
You need to concatenate the arguments you want to pass (open and alias myFile) with the contents of buffer.
The code can also be much simplified by replacing malloc with an automatic array. You don't need to malloc it because you don't need it outside of the block scope. (And you shouldn't be using malloc in C++ code anyway; use new[] instead.)
Here's a modified snippet of the code shown in your question:
(Warning: changes made using only my eyes as a compiler! Handle with care.)
if(GetOpenFileName(&ofn))
{
// Get the short path name, and place it in the buffer array.
// We know that a short path won't be any longer than MAX_PATH, so we can
// simply allocate a statically-sized array without futzing with new[].
//
// Note: In production code, you should probably check the return value
// of the GetShortPathName function to make sure it succeeded.
TCHAR buffer[MAX_PATH];
GetShortPathName(szFileName, buffer, MAX_PATH);
// Add the short path name to your ListBox control.
//
// Note: In C++ code, you should probably use C++-style casts like
// reinterpret_cast, rather than C-style casts!
SendMessage(hList, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(buffer));
// Build the argument string to pass to the mciSendString function.
//
// Note: In production code, you probably want to use the more secure
// alternatives to the string concatenation functions.
// See the documentation for more details.
// And, as before, you should probably check return values for error codes.
TCHAR arguments[MAX_PATH * 2]; // this will definitely be large enough
lstrcat(arguments, TEXT("open"));
lstrcat(arguments, buffer);
lstrcat(arguments, TEXT("alias myFile"));
// Or, better yet, use a string formatting function, like StringCbPrintf:
// StringCbPrintf(arguments, MAX_PATH * 2, TEXT("open %s alias myFile"),
// buffer);
// Call the mciSendString function with the argument string we just built.
mciSendString(arguments, NULL, 0, NULL);
mciSendString("play myFile", NULL, 0, NULL);
}
Do note that, as the above code shows, working with C-style strings (character arrays) is a real pain in the ass. C++ provides a better alternative, in the form of the std::string class. You should strongly consider using that instead. To call Windows API functions, you'll still need a C-style string, but you can get one of those by using the c_str method of the std::string class.

How to tell if I'm leaking IMalloc memory?

I'd like to just know if there is a well-established standard way to ensure that one's process doesn't leak COM based resources (such as IMalloc'd objects)?
Take the following code as an example:
HRESULT STDMETHODCALLTYPE CShellBrowserDialog::OnStateChange(__RPC__in_opt IShellView *ppshv, ULONG uChange)
{
TRACE("ICommDlgBrowser::OnStateChange\n");
if (uChange == CDBOSC_SELCHANGE)
{
CComPtr<IDataObject> data;
if (ppshv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&data) == S_OK )
{
UINT cfFormat = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
FORMATETC fmtetc = { cfFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stgmed;
if (data->GetData(&fmtetc, &stgmed) == S_OK)
{
TCHAR path[MAX_PATH];
// check if this single selection (or multiple)
CIDA * cida = (CIDA*)stgmed.hGlobal;
if (cida->cidl == 1)
{
const ITEMIDLIST * pidlDirectory = (const ITEMIDLIST *)(((LPBYTE)cida) + cida->aoffset[0]);
const ITEMIDLIST * pidlFile = (const ITEMIDLIST *)(((LPBYTE)cida) + cida->aoffset[1]);
ITEMIDLIST * pidl = Pidl_Concatenate(pidlDirectory, pidlFile);
// we now have the absolute pidl of the currently selected filesystem object
if (!SHGetPathFromIDList(pidl, path))
strcpy_s(path, _T("<this object has no path>"));
// free our absolute pidl
Pidl_Free(pidl);
}
else if (cida->cidl > 1)
strcpy_s(path, _T("{multiple selection}"));
else
strcpy_s(path, _T("-"));
// trace the current selection
TRACE(_T(" Current Selection = %s\n"), path);
// release the data
ReleaseStgMedium(&stgmed);
}
}
}
return E_NOTIMPL;
}
So in the above code, I have at least three allocations that occur in code that I call, with only one of them being properly cleaned up automatically. The first is the acquisition of IDataObject pointer, which increments that object's reference count. CComPtr<> takes care of that issue for me.
But then there is IDataObject::GetData, which allocates an HGLOBAL for me. And a utility function Pidl_Concatenate which creates a PIDL for me (code left out, but you can imagine it does the obvious thing, via IMalloc::Alloc()). I have another utility Pidl_Free which releases that memory for me, but must be manually called [which makes the code in question full of exception safety issues (its utterly unsafe as its currently written -- I hate MS's coding mechanics - just asking for memory to fail to be released properly].
I will enhance this block of code to have a PIDL class of some sort, and probably a CIDA class as well, to ensure that they're properly deallocated even in the face of exceptions. But I would still like to know if there is a good utility or idiom for writing COM applications in C++ that can ensure that all IMallocs and AddRef/Dispose are called for that application's lifetime!
Implementing the IMallocSpy interface (see CoRegisterMallocSpy Function) may help get you some of the way.
Note that this is for debugging only, and be careful. There are cautionary tales on the web...
You can not free the global handle returned by IDataObject::GetData, otherwise other programs can not paste from the clipboard after the data is cleaned up.
Any pidl you get from shell needs to be freed using IMalloc::Free or ILFree (same effect once OLE32.DLL is loaded into the process). Exceptions are pointers to the middle of item list which can not be freed independently. If you are worried about exceptions, guard your code with try/catch/finally and put the free code in the finally block.

Windows - Prevent crashes "Checking for a solution..." and "Restarting the program..."

This may not be a purely programming related question, but I come across this often during development. When my app crashes and I choose to kill it, Windows automatically throws up a "Checking for a solution..." dialog box. When I hit the cancel button on that I get another dialog box that says "Restarting the program..." Is there a way to prevent this behavior? When I stop an app I'd prefer if it were silently killed. I'm using Windows 7 if the platform is important.
Although Microsoft recommends using a newer replacement API available only on Windows Vista and later, there is an API which works for all versions of Windows from XP onward: AddERExcludedApplication(). This function takes the module name without path information (e.g., "myprogram.exe") for which error reporting is to be disabled.
The new method available only Windows Vista and later is to call WerAddExcludedApplication() function. This API allows you to specify whether it should change the HKEY_CURRENT_USER registry hive, or the HKEY_LOCAL_MACHINE registry hive. Be sure to set this for the HKCU if the HKLM set fails, such as:
typedef BOOL (*ADD_MER_EXCLUDED_APP_XP) (PCWSTR);
typedef BOOL (*ADD_MER_EXCLUDED_APP_VISTA) (PCWSTR, BOOL);
bool disable_microsoft_error_reporting(PCWSTR wz_app)
{
const WCHAR * const WZ_MER_DLL_XP = L"faultrep.dll";
const char * const SZ_MER_PROC_XP = "AddERExcludedApplicationW";
const WCHAR * const WZ_MER_DLL_VISTA = L"wer.dll";
const char * const SZ_MER_PROC_VISTA = "WerAddExcludedApplicationW";
const int WER_EXCLUDE_FOR_ALL_USERS = TRUE;
const int WER_EXCLUDE_FOR_THIS_USER = FALSE;
HANDLE hlib_error_reports_xp = NULL;
HANDLE hlib_error_reports_vista = NULL;
ADD_MER_EXCLUDED_APP_XP add_mer_excluded_app_xp = NULL;
ADD_MER_EXCLUDED_APP_VISTA add_mer_excluded_app_vista = NULL;
bool success = false;
// First, attempt the API that has been around since XP.
hlib_error_reports_xp = LoadLibrary(WZ_MER_DLL_XP);
if (hlib_error_reports_xp)
{
add_mer_excluded_app_xp = (ADD_MER_EXCLUDED_APP_XP)GetProcAddress(hlib_error_reports_xp, SZ_MER_PROC_XP);
if (add_mer_excluded_app_xp)
success = add_mer_excluded_app_xp(wz_app);
FreeLibrary(hlib_error_reports_xp);
hlib_error_reports_xp = NULL;
add_mer_excluded_app_xp = NULL;
if (success)
return true;
}
// That did not succeed. Attempt the Vista API.
hlib_error_reports_vista = LoadLibrary(WZ_MER_DLL_VISTA);
if (hlib_error_reports_vista)
{
add_mer_excluded_app_vista = (ADD_MER_EXCLUDED_APP_VISTA)GetProcAddress(hlib_error_reports_vista, SZ_MER_PROC_VISTA);
if (add_mer_excluded_app_vista)
{
success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_ALL_USERS));
if (!success)
success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_THIS_USER));
}
FreeLibrary(hlib_error_reports_vista);
hlib_error_reports_vista = NULL;
add_mer_excluded_app_vista = NULL;
if (success)
return true;
}
// Nothing worked. Fail.
return false;
}
To further curtail the execution of the WER components, imeplement an unhandled exception filter and pass it to: SetUnhandledExceptionFilter() function. To shunt WER, your filter must never return EXCEPTION_CONTINUE_SEARCH or EXCEPTION_EXECUTE_HANDLER.
One of the drawbacks of implementing the SetUnhandledExceptionFilter() function is that it interferes with Just-in-time debugging.
You mention you want the app to be "silently killed." In that case:
LONG WINAPI global_exception_filter(struct _EXCEPTION_POINTERS *exception_info)
{
ExitProcess(0xDEDD000D);
}
int WINAPI WinMain(
HINSTANCE _hinstance,
HINSTANCE hinstance_prev,
LPSTR sz_cmd_line,
int cmd_show
)
{
SetUnhandledExceptionFilter(global_exception_filter);
/* ... */
}
Will cause the application to immediately vanish upon unhandled exception. N.B., the exit code to return is a matter of taste.
Check out the answers on these questions:
How do I disable the ‘Debug / Close Application’ dialog on Windows Vista?
Hide Error Report window
I realize that others have answered with ways to work around this, but...
Let's not forget that the best way to protect against this is to write a program that doesn't crash. :-) You shouldn't be seeing this if you are using memory correctly and not hanging the GUI thread.
Altering the behavior of an application crash is a great way to introduce subtle and deadly bugs. See also this blog post from Microsoft's Raymond Chen.
Take a look at the Windows Error Reporting APIs.

Resources