error LNK2019: unresolved external symbol Direct Sound - c++

So I'm reading "Beginning Game Programming Third Edition" by Jonathan S. Harbour, and I've gotten to the point where he teaches us how to use Direct Sound. The book uses it's own DirectSound.h and DirectSound.cpp files, which were from a previous release of the DirectX SDK, but when I try to compile I get the "LNK2019: unresolved external symbol" error.
1>DirectSound.obj : error LNK2019: unresolved external symbol
_DXTraceA#20 referenced in function "public: long thiscall CSoundManager::Initialize(struct HWND *,unsigned long)"
(?Initialize#CSoundManager##QAEJPAUHWND__##K#Z)
1>DirectSound.obj : error LNK2019: unresolved external symbol
_DirectSoundCreate8#12 referenced in function "public: long thiscall CSoundManager::Initialize(struct HWND *,unsigned long)"
(?Initialize#CSoundManager##QAEJPAUHWND__##K#Z)
I have not implemented any Direct Sound code in my project as yet, the mere presence of these files causes the project to not compile. Without them, the project compiles and runs perfectly.
#ifndef DSUTIL_H
#define DSUTIL_H
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <dsound.h>
class CSoundManager;
class CSound;
class CStreamingSound;
class CWaveFile;
#define WAVEFILE_READ 1
#define WAVEFILE_WRITE 2
#define DSUtil_StopSound(s) { if(s) s->Stop(); }
#define DSUtil_PlaySound(s) { if(s) s->Play( 0, 0 ); }
#define DSUtil_PlaySoundLooping(s) { if(s) s->Play( 0, DSBPLAY_LOOPING ); }
//-----------------------------------------------------------------------------
// Name: class CSoundManager
// Desc:
//-----------------------------------------------------------------------------
class CSoundManager
{
protected:
LPDIRECTSOUND8 m_pDS;
public:
CSoundManager();
~CSoundManager();
HRESULT Initialize(HWND hWnd, DWORD dwCoopLevel);
inline LPDIRECTSOUND8 GetDirectSound() { return m_pDS; }
HRESULT SetPrimaryBufferFormat( DWORD dwPrimaryChannels, DWORD dwPrimaryFreq, DWORD dwPrimaryBitRate );
HRESULT Create( CSound** ppSound, LPTSTR strWaveFileName, DWORD dwCreationFlags = 0, GUID guid3DAlgorithm = GUID_NULL, DWORD dwNumBuffers = 1 );
};
//-----------------------------------------------------------------------------
// Name: class CSound
// Desc: Encapsulates functionality of a DirectSound buffer.
//-----------------------------------------------------------------------------
class CSound
{
protected:
LPDIRECTSOUNDBUFFER* m_apDSBuffer;
DWORD m_dwDSBufferSize;
CWaveFile* m_pWaveFile;
DWORD m_dwNumBuffers;
DWORD m_dwCreationFlags;
HRESULT RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, BOOL* pbWasRestored );
public:
CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags );
virtual ~CSound();
HRESULT FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, BOOL bRepeatWavIfBufferLarger );
LPDIRECTSOUNDBUFFER GetFreeBuffer();
HRESULT Play( DWORD dwPriority = 0, DWORD dwFlags = 0, LONG lVolume = 0, LONG lFrequency = -1, LONG lPan = 0 );
HRESULT Stop();
HRESULT Reset();
BOOL IsSoundPlaying();
};
//-----------------------------------------------------------------------------
// Name: class CWaveFile
// Desc: Encapsulates reading or writing sound data to or from a wave file
//-----------------------------------------------------------------------------
class CWaveFile
{
public:
WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure
HMMIO m_hmmio; // MM I/O handle for the WAVE
MMCKINFO m_ck; // Multimedia RIFF chunk
MMCKINFO m_ckRiff; // Use in opening a WAVE file
DWORD m_dwSize; // The size of the wave file
MMIOINFO m_mmioinfoOut;
DWORD m_dwFlags;
BOOL m_bIsReadingFromMemory;
BYTE* m_pbData;
BYTE* m_pbDataCur;
ULONG m_ulDataSize;
CHAR* m_pResourceBuffer;
protected:
HRESULT ReadMMIO();
HRESULT WriteMMIO( WAVEFORMATEX *pwfxDest );
public:
CWaveFile();
~CWaveFile();
HRESULT Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags );
HRESULT Close();
HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote );
DWORD GetSize();
HRESULT ResetFile();
WAVEFORMATEX* GetFormat() { return m_pwfx; };
};
#endif // DSUTIL_H
///////////////////////////////////////////////////////////////////////////////
// The function that causes the error
HRESULT CSoundManager::Initialize(HWND hWnd, DWORD dwCoopLevel)
{
HRESULT hr;
SAFE_RELEASE(m_pDS);
// Create IDirectSound using the primary sound device
if(FAILED(hr = DirectSoundCreate8(NULL, &m_pDS, NULL)))
return DXTRACE_ERR(TEXT("DirectSoundCreate8"), hr);
// Set DirectSound coop level
if( FAILED( hr = m_pDS->SetCooperativeLevel( hWnd, dwCoopLevel ) ) )
return DXTRACE_ERR( TEXT("SetCooperativeLevel"), hr );
return S_OK;
}

Error LNK2019 is about adding a missing library - a typical problem. You should identify missing symbols, then identify library to additionally link, then add it using #pragma or via project settings.
Also as it's a beginner question, most likely Stack Overflow already has something closely related. Be always sure to run a search for it, compare code snippets to yours.
Application works in visual studio but release/debug exe does not
Which header should I include for DXTrace?
Related questions show that you need dsound.lib and dxerr.lib to be linked in.

Related

In vc6.0, using WinAPI to open the program to expand the monitor some problems

Below is the main code, the problems encountered, and how they were resolved
***.h
std::list<DISPLAY_DEVICE> m_vDisplayDevice_list;
std::list<DEVMODE> m_vDevmode_list;
int m_nDisplayScreen;
***.cpp
std::list<DISPLAY_DEVICE> devices;
std::list<DEVMODE> modes;
int devId = 0;
BOOL ret = false; // bool ret = false;
bool isPrimary = false;
//list all DisplayDevices (Monitors)
do
{
DISPLAY_DEVICE displayDevice;
ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
displayDevice.cb = sizeof(displayDevice);
ret = EnumDisplayDevices(NULL, devId, &displayDevice, 0);
if (ret != 0) // reinterpret_cast
{
// 有‘DISPLAY_DEVICE_ATTACHED_TO_DESKTOP’标志的显示设备
if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
{
devices.push_back(displayDevice);
isPrimary = ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) == DISPLAY_DEVICE_PRIMARY_DEVICE);
}
}
devId++;
} while (ret);
m_vDisplayDevice_list = devices;
std::list<DISPLAY_DEVICE>::iterator it;
for (it = m_vDisplayDevice_list.begin(); it != m_vDisplayDevice_list.end(); it++)
{
DEVMODE deviceMode;
deviceMode.dmSize = sizeof(DEVMODE);
deviceMode.dmFields = DM_PELSWIDTH | // dmPelsWidth
DM_PELSHEIGHT | //dmPelsHeight
DM_BITSPERPEL |
DM_POSITION |
DM_DISPLAYFREQUENCY |
DM_DISPLAYFLAGS; // | DM_DISPLAYORIENTATION;
EnumDisplaySettings((const char*)(it->DeviceName), (int)ENUM_REGISTRY_SETTINGS, &deviceMode);
modes.push_back(deviceMode);
}
m_vDevmode_list = modes;
I used this function to open the Windows desktop shortcut:
ShellExecute(NULL,
NULL,
_T("C:\\Users\\Administrator\\Desktop\\BasePointV - ***.lnk"),
NULL,
NULL,
SW_SHOWNORMAL);
I have a problem:
--------Configuration: Display - Win32 Release--------
Linking...
***.obj : error LNK2001: unresolved external symbol __imp__EnumDisplayDevicesA#16
Debug/***.exe : fatal error LNK1120: 1 unresolved externals
***.exe - 1 error(s), 0 warning(s)
The project I built is MFC AppWinzard(exe);
Environment is:Windows10 VC 6.0
Online solutions include:
Define WINVER 0x0500
Add user32.DLL
There are many good solutions, but the linking problem is not solved yet!
Your linkage error concerning _EnumDisplayDevices says it all.
My psychic powers suggests that since Visual Studio 6.0 (released in 1998) predates the availability of EnumDisplayDevices (Windows 2000), you are trying to pre-declare the API yourself. You probably predeclared EnumDisplayDevices manually yourself. Something like this:
BOOL EnumDisplayDevices(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags
);
There's two problems with this approach.
First, there's no API called EnumDisplayDevices. There is however, two APIs called EnumDisplayDevicesA and EnumDisplayDevicesW for both Unicode and ANSI builds. The Windows SDK will use a macro to map either one to the thing you can to invoke:
#ifdef UNICODE
#define EnumDisplayDevices EnumDisplayDevicesW
#else
#define EnumDisplayDevices EnumDisplayDevicesA
#endif // !UNICODE
Second, the actual declaration of EnumDisplayDevicesA and EnumDisplayDevicesW will are declared as stdcall calling type, like most Win32 APIs. Your declaration is likely missing this detail.
Hence, you want to declare this:
BOOL __stdcall EnumDisplayDevicesW(
LPCWSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEW lpDisplayDevice,
DWORD dwFlags);
And this:
BOOL __stdcall EnumDisplayDevicesA(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags);
If you manually declared DISPLAY_DEVICE and PDISPLAY_DEVICE yourself, you may also need to fixup your declaration as well. That's addressed in the sample code below.
Finally, even after you fix this, you still won't have a lib to link with since your version of user32.lib doesn't know anything about this API that came later.
You could find a newer version of the Windows SDK that still works with VC 6.0. But a simpler approach might to LoadLibrary the API directly at runtime. So putting it all together, here's a complete solution in which we'll dynamically load the EnumDisplayDevicesW and EnumDisplayDevicesA functions at runtime. Sample invocation as well:
#include <windows.h>
// BORROWED THIS FROM THE WINDOWS SDK - uncomment it if you need it
#if 0
typedef struct _DISPLAY_DEVICEA {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD StateFlags;
CHAR DeviceID[128];
CHAR DeviceKey[128];
} DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA;
typedef struct _DISPLAY_DEVICEW {
DWORD cb;
WCHAR DeviceName[32];
WCHAR DeviceString[128];
DWORD StateFlags;
WCHAR DeviceID[128];
WCHAR DeviceKey[128];
} DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
#ifdef UNICODE
typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
#else
typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
#endif // UNICODE
#endif // if 0
// Declare the function types for EnumDisplayDevices
typedef BOOL(__stdcall* FN_EDD_W)(LPCWSTR, DWORD, PDISPLAY_DEVICEW, DWORD);
typedef BOOL(__stdcall* FN_EDD_A)(LPCSTR, DWORD, PDISPLAY_DEVICEA, DWORD);
int main()
{
FN_EDD_W fnEnumDisplayDevicesW;
FN_EDD_A fnEnumDisplayDevicesA;
// Dynamically load EnumDisplayDevices
HMODULE hMod = LoadLibraryW(L"user32.dll");
fnEnumDisplayDevicesW = (FN_EDD_W)GetProcAddress(hMod, "EnumDisplayDevicesW");
fnEnumDisplayDevicesA = (FN_EDD_A)GetProcAddress(hMod, "EnumDisplayDevicesA");
// now invoke the loaded API function
DISPLAY_DEVICEW device = {};
device.cb = sizeof(device);
fnEnumDisplayDevicesW(NULL, 0, &device, 0); // equivalent to EnumDisplayDevicesW
}

LNK2019 with a sample from MSDN

Tried to copy the code from the .cpp file in Common File Dialog Sample got some LNK2019. It seems like a problem with the linking of 3 functions.
Here are the errors:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol __imp_TaskDialog referenced in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl CDialogEventHandler::ChooseFromFolder(void)" (?ChooseFromFolder#CDialogEventHandler##QEAA?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) Build-A-Font C:\Users\nadav\Desktop\SFML\Build-A-Font\Build-A-Font\FileDialog.obj 1
Error LNK2019 unresolved external symbol __imp_PSGetPropertyDescriptionListFromString referenced in function "public: virtual long __cdecl CDialogEventHandler::OnTypeChange(struct IFileDialog *)" (?OnTypeChange#CDialogEventHandler##UEAAJPEAUIFileDialog###Z) Build-A-Font C:\Users\nadav\Desktop\SFML\Build-A-Font\Build-A-Font\FileDialog.obj 1
Error LNK2019 unresolved external symbol QISearch referenced in function "public: virtual long __cdecl CDialogEventHandler::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface#CDialogEventHandler##UEAAJAEBU_GUID##PEAPEAX#Z) Build-A-Font C:\Users\nadav\Desktop\SFML\Build-A-Font\Build-A-Font\FileDialog.obj 1
That is their code after some modifications for my needs:
#pragma once
#define STRICT_TYPED_ITEMIDS
#include <shlobj.h>
#include <shlwapi.h>
#include <string>
#include <sstream>
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
// Added for changing the entry point
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
const COMDLG_FILTERSPEC c_rgSaveTypes[] =
{
{L"Word Document (*.doc; *.docx)", L"*.doc;*.docx"},
{L"Powerpoint Presentation (*.ppt; *.pptx)", L"*.ppt;*.pptx"},
{L"Web Page (*.htm; *.html)", L"*.htm;*.html"},
{L"Text Document (*.txt)", L"*.txt"},
{L"All Documents (*.*)", L"*.*"}
};
// Indices of file types
#define INDEX_WORDDOC 1
#define INDEX_PRPNTPR 2
#define INDEX_WEBPAGE 3
#define INDEX_TEXTDOC 4
// Controls
#define CONTROL_GROUP 2000
#define CONTROL_RADIOBUTTONLIST 2
#define CONTROL_RADIOBUTTON1 1
#define CONTROL_RADIOBUTTON2 2 // It is OK for this to have the same ID as CONTROL_RADIOBUTTONLIST,
// because it is a child control under CONTROL_RADIOBUTTONLIST
// IDs for the Task Dialog Buttons
#define IDC_BASICFILEOPEN 100
/* File Dialog Event Handler *****************************************************************************************************/
class CDialogEventHandler : public IFileDialogEvents,
public IFileDialogControlEvents
{
public:
// IUnknown methods
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(CDialogEventHandler, IFileDialogEvents),
QITABENT(CDialogEventHandler, IFileDialogControlEvents),
{ 0 },
#pragma warning(suppress:4838)
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&_cRef);
}
IFACEMETHODIMP_(ULONG) Release()
{
long cRef = InterlockedDecrement(&_cRef);
if (!cRef)
delete this;
return cRef;
}
// IFileDialogEvents methods
IFACEMETHODIMP OnFileOk(IFileDialog*) { return S_OK; };
IFACEMETHODIMP OnFolderChange(IFileDialog*) { return S_OK; };
IFACEMETHODIMP OnFolderChanging(IFileDialog*, IShellItem*) { return S_OK; };
IFACEMETHODIMP OnHelp(IFileDialog*) { return S_OK; };
IFACEMETHODIMP OnSelectionChange(IFileDialog*) { return S_OK; };
IFACEMETHODIMP OnShareViolation(IFileDialog*, IShellItem*, FDE_SHAREVIOLATION_RESPONSE*) { return S_OK; };
IFACEMETHODIMP OnOverwrite(IFileDialog*, IShellItem*, FDE_OVERWRITE_RESPONSE*) { return S_OK; };
// This method gets called when the file-type is changed (combo-box selection changes).
// For sample sake, let's react to this event by changing the properties show.
IFACEMETHODIMP OnTypeChange(IFileDialog* pfd)
{
IFileSaveDialog* pfsd;
HRESULT hr = pfd->QueryInterface(&pfsd);
if (SUCCEEDED(hr))
{
UINT uIndex;
hr = pfsd->GetFileTypeIndex(&uIndex); // index of current file-type
if (SUCCEEDED(hr))
{
IPropertyDescriptionList* pdl = NULL;
switch (uIndex)
{
case INDEX_WORDDOC:
// When .doc is selected, let's ask for some arbitrary property, say Title.
hr = PSGetPropertyDescriptionListFromString(L"prop:System.Title", IID_PPV_ARGS(&pdl));
if (SUCCEEDED(hr))
{
// FALSE as second param == do not show default properties.
hr = pfsd->SetCollectedProperties(pdl, FALSE);
pdl->Release();
}
break;
case INDEX_WEBPAGE:
// When .html is selected, let's ask for some other arbitrary property, say Keywords.
hr = PSGetPropertyDescriptionListFromString(L"prop:System.Keywords", IID_PPV_ARGS(&pdl));
if (SUCCEEDED(hr))
{
// FALSE as second param == do not show default properties.
hr = pfsd->SetCollectedProperties(pdl, FALSE);
pdl->Release();
}
break;
case INDEX_TEXTDOC:
// When .txt is selected, let's ask for some other arbitrary property, say Author.
hr = PSGetPropertyDescriptionListFromString(L"prop:System.Author", IID_PPV_ARGS(&pdl));
if (SUCCEEDED(hr))
{
// TRUE as second param == show default properties as well, but show Author property first in list.
hr = pfsd->SetCollectedProperties(pdl, TRUE);
pdl->Release();
}
break;
}
}
pfsd->Release();
}
return hr;
};
// IFileDialogControlEvents methods
// This method gets called when an dialog control item selection happens (radio-button selection. etc).
// For sample sake, let's react to this event by changing the dialog title.
IFACEMETHODIMP OnItemSelected(IFileDialogCustomize* pfdc, DWORD dwIDCtl, DWORD dwIDItem)
{
IFileDialog* pfd = NULL;
HRESULT hr = pfdc->QueryInterface(&pfd);
if (SUCCEEDED(hr))
{
if (dwIDCtl == CONTROL_RADIOBUTTONLIST)
{
switch (dwIDItem)
{
case CONTROL_RADIOBUTTON1:
hr = pfd->SetTitle(L"Longhorn Dialog");
break;
case CONTROL_RADIOBUTTON2:
hr = pfd->SetTitle(L"Vista Dialog");
break;
}
}
pfd->Release();
}
return hr;
};
IFACEMETHODIMP OnButtonClicked(IFileDialogCustomize*, DWORD) { return S_OK; };
IFACEMETHODIMP OnCheckButtonToggled(IFileDialogCustomize*, DWORD, BOOL) { return S_OK; };
IFACEMETHODIMP OnControlActivating(IFileDialogCustomize*, DWORD) { return S_OK; };
CDialogEventHandler() : _cRef(1) { };
private:
~CDialogEventHandler() { };
long _cRef;
};
// Instance creation helper
HRESULT CDialogEventHandler_CreateInstance(REFIID riid, void** ppv)
{
*ppv = NULL;
CDialogEventHandler* pDialogEventHandler = new (std::nothrow) CDialogEventHandler();
HRESULT hr = pDialogEventHandler ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
hr = pDialogEventHandler->QueryInterface(riid, ppv);
pDialogEventHandler->Release();
}
return hr;
}
// This code snippet demonstrates how to work with the common file dialog interface
std::string BasicFileOpen()
{
// CoCreate the File Open Dialog object.
IFileDialog* pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (SUCCEEDED(hr))
{
// Create an event handling object, and hook it up to the dialog.
IFileDialogEvents* pfde = NULL;
hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
if (SUCCEEDED(hr))
{
// Hook up the event handler.
DWORD dwCookie;
hr = pfd->Advise(pfde, &dwCookie);
if (SUCCEEDED(hr))
{
// Set the options on the dialog.
DWORD dwFlags;
// Before setting, always get the options first in order not to override existing options.
hr = pfd->GetOptions(&dwFlags);
if (SUCCEEDED(hr))
{
// In this case, get shell items only for file system items.
hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
if (SUCCEEDED(hr))
{
// Set the file types to display only. Notice that, this is a 1-based array.
hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
if (SUCCEEDED(hr))
{
// Set the selected file type index to Word Docs for this example.
hr = pfd->SetFileTypeIndex(INDEX_WORDDOC);
if (SUCCEEDED(hr))
{
// Set the default extension to be ".doc" file.
hr = pfd->SetDefaultExtension(L"doc");
if (SUCCEEDED(hr))
{
// Show the dialog
hr = pfd->Show(NULL);
if (SUCCEEDED(hr))
{
// Obtain the result, once the user clicks the 'Open' button.
// The result is an IShellItem object.
IShellItem* psiResult;
hr = pfd->GetResult(&psiResult);
if (SUCCEEDED(hr))
{
// We are just going to print out the name of the file for sample sake.
PWSTR pszFilePath = NULL;
hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr))
{
TaskDialog(NULL,
NULL,
L"CommonFileDialogApp",
pszFilePath,
NULL,
TDCBF_OK_BUTTON,
TD_INFORMATION_ICON,
NULL);
CoTaskMemFree(pszFilePath);
}
psiResult->Release();
}
}
}
}
}
}
}
// Unhook the event handler.
pfd->Unadvise(dwCookie);
}
pfde->Release();
}
pfd->Release();
}
TCHAR filepath[1024];
if (hr == S_OK)
{
std::stringstream pff;
pff << filepath;
return pff.str();
}
return "";
}
I changed their code in the original files I downloaded from the github and it worked just fine. I tried to copy it to another project and it just won't work (the LNK2019 errors)
I thought I'd provide a sort of meta-answer to this: how did Jerry know what libraries you need to link with? And, as ever, the answer lies in the documentation.
First of all, let's take a look at those linker errors (I've cut them down a bit for clarity, using templates usually tends to lead to verbose / hard to read error messages):
Unresolved symbol __imp_TaskDialog referenced in function <irrelevant>
Unresolved symbol __imp_PSGetPropertyDescriptionListFromString referenced in function <irrelevant>
Unresolved symbol QISearch referenced in function <irrelevant>
First up, you can ignore the __imp_ bit. This just tells you that the function is imported from a DLL. So that leaves us with the following unresolved references:
TaskDialog
PSGetPropertyDescriptionListFromString
QISearch
So, time to go Googling.
The documentation for TaskDialog is here, and if you scroll down to the 'requirements' section at the bottom of the page you will see:
Library Comctl32.lib
So that's nailed that one (note that capitalisation doesn't matter here, I don't know why Microsoft document this stuff in such a weird way).
In a similar vein, we can easily discover that PSGetPropertyDescriptionListFromString is in Propsys.lib, and QISearch is in Shlwapi.lib. End of story.
I hope that shows you how it's done. Every Windows developer needs to understand how to do this and how to find and read the (extensive) documentation that Microsoft provide in general.

ITpmVirtualSmartCardManager::CreateVirtualSmartCard the PIN is not set correctly

I follow this thread to create TPM Vistual Smnart Card, after run the app the virtual smart card created and could see in Device Manager, but when I try to insert the PIN 123456789 to authenticate show the PIN is not correct
#include "Tpmvscmgr.h"
#include "StrSafe.h"
#pragma comment (lib, "Vscmgr.lib")
#include <Windows.h>
HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];
StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID) / sizeof(wszCLSID[0]));
HRESULT hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName) / sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
if (FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
return CoGetObject(wszMonikerName, &bo, riid, ppv);
}
int main()
{
HRESULT hr = S_OK;
HWND hwnd = NULL;
ITpmVirtualSmartCardManager *pObj = NULL;
CoInitialize(NULL);
hr = CoCreateInstanceAsAdmin(
hwnd,
CLSID_TpmVirtualSmartCardManager,
IID_ITpmVirtualSmartCardManager,
(void**)&pObj);
//ITpmVirtualSmartCardManager *pObj = NULL;
LPWSTR friendly = L"Friendly";
LPWSTR out = L"";
BYTE pin[] = "123456789";
DWORD size = sizeof(pin);
BOOL boot;
hr = pObj->CreateVirtualSmartCard(friendly, TPMVSC_DEFAULT_ADMIN_ALGORITHM_ID, pin, size, NULL, 0, pin, size, pin, size, false, NULL, &out, &boot);
return 0;
}
Any one has any idea what the problem?
The fourth parameter to CreateVirtualSmartCard() must be 24. It shouldn't be the same thing as PIN anyway.
sizeof(pin) will return 10 in this case, because the null terminator is included in computing the size. Is this what TpmVscMgr does as well?

hook COM interface throw vTable

I'm trying hook custom Credentential Provider UI, based on ICredentialProvider interface.
Using this guide(Vtable Patching) , i'm succesufly hook COM interface.
But trouble with hooking GetCredentenialAt method, i'm set vtable index equal to 10, and try relogin.
LogonUI screen blinking on :Ctrl+Alt+Del Screen:.
my source code:
#include "stdafx.h"
#include "VtableHooks.h"
#include "credentialprovider.h"
namespace Hook
{
STDMETHODIMP GetCredentialAt(IUnknown* This, DWORD dwIndex, ICredentialProviderCredential** ppcpc);
STDMETHODIMP QueryInterface(IUnknown* This, REFIID riid, void **ppvObject);
}
struct Context
{
Context(): m_Name("Hooked object"){}
PVOID m_OriginalQueryInterface;
PVOID m_OriginalGetCredentialAt;
ATL::CComBSTR m_Name;
};
std::auto_ptr<Context> g_Context;
HRESULT HookMethod(IUnknown* original, PVOID proxyMethod, PVOID* originalMethod, DWORD vtableOffset)
{ PVOID* originalVtable = *(PVOID**)original;
if (originalVtable[vtableOffset] == proxyMethod)
return S_OK;
*originalMethod = originalVtable[vtableOffset];
originalVtable[vtableOffset] = proxyMethod;
return S_OK;
}
HRESULT InstallComInterfaceHooks(IUnknown* originalInterface, REFIID riid)
{
HRESULT hr = S_OK;
if (riid == IID_ICredentialProvider)
{
// Only single instance of a target object is supported in the sample
if (g_Context.get())return E_FAIL;
ATL::CComPtr<ICredentialProvider> so;
HRESULT hr = originalInterface->QueryInterface(IID_ICredentialProvider, (void**)&so);
if (FAILED(hr)) return hr; // we need this interface to be present
// remove protection from the vtable
DWORD dwOld = 0;
if (!::VirtualProtect(*(PVOID**)(originalInterface), sizeof(LONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld))
return E_FAIL;
// hook interface methods
g_Context.reset(new Context);
HookMethod(so, (PVOID)Hook::QueryInterface, &g_Context->m_OriginalQueryInterface, 0);
HookMethod(so, (PVOID)Hook::GetCredentialAt, &g_Context->m_OriginalGetCredentialAt, 10);
}
return hr;
}
typedef HRESULT (WINAPI *QueryInterface_T)(IUnknown* This, REFIID riid, void **ppvObject);
STDMETHODIMP Hook::QueryInterface(IUnknown* This, REFIID riid, void **ppvObject)
{
QueryInterface_T qi = (QueryInterface_T)g_Context->m_OriginalQueryInterface;
HRESULT hr = qi(This, riid, ppvObject);
return hr;
}
typedef HRESULT(WINAPI *GetCredentialAt_T)(IUnknown* This, DWORD dwIndex, ICredentialProviderCredential** ppcpc);
STDMETHODIMP Hook::GetCredentialAt(IUnknown* This, DWORD dwIndex, ICredentialProviderCredential** ppcpc)
{
GetCredentialAt_T qi = (GetCredentialAt_T)g_Context->m_OriginalGetCredentialAt;
HRESULT hr = qi(This, dwIndex, ppcpc);
return hr;
}
Using IDA, i'm showing load 3rd custom dll. This Dll break interface.

How to resolve the Winusb linking error?

I've written a WinUSB project for obtaining data from spectrometer, the code seems to work few weeks ago. In the later stage I tried to link this project with CUDA, after few trials I solved the CUDA linker error. Unfortunately I ended up "error LNK2019: unresolved external symbol" in my main program(Winusb project). At first I thought it was because of the .cu files and I decided to remove all the .CU(CUDA)files form the project and still I was keep on getting the same error(LNK2019).
The following is my code for Winusb project (which was working perfectly few weeks back, but now I'm completely lost and needed some help)
Main.cpp
#include "pch.h"
#include <cstdio>
LONG __cdecl _tmain(LONG Argc, LPTSTR * Argv )
{
FILE *output_file1 = fopen("output_file2.txt", "w");
//FILE *output_file2 = fopen("output_file3.txt", "w");
DEVICE_DATA deviceData;
HRESULT hr;
USB_DEVICE_DESCRIPTOR deviceDesc;
BOOL bResult;
BOOL noDevice;
ULONG lengthReceived;
BOOL wrResult = TRUE;
BOOL wr1Result = TRUE;
BOOL RQResult = 0;
UNREFERENCED_PARAMETER(Argc);
UNREFERENCED_PARAMETER(Argv);
//////////////////////Open device ///////////////
hr = OpenDevice(&deviceData, &noDevice);
if (FAILED(hr)) {
if (noDevice) {
printf(_T("Device not connected or driver not installed\n"));
} else {
printf(_T("Failed looking for device, HRESULT 0x%x\n"), hr);
}
std::getchar();
return 0;
}
/////////////////////Get descriptor//////////////////
bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle,
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
(PBYTE) &deviceDesc,
sizeof(deviceDesc),
&lengthReceived);
if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {
printf(_T("Error among LastError %d or lengthReceived %d\n"),
FALSE == bResult ? GetLastError() : 0,
lengthReceived);
CloseDevice(&deviceData);
return 0;
}
bool sResult = FALSE;bool syResult;
bool sResult1 = FALSE;bool syResult1;
//Initialize
UCHAR Intialize[] = {0x01};
ULONG cbISize = strlen((char*)Intialize);
ULONG InSent = 0;
wrResult = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, Intialize, 1, &InSent, 0);
//Integration time - 700ms
UCHAR Inttime[] = {0x0200100000};
ULONG cbITSize = strlen((char*)Inttime);
ULONG InttimeSent = 0;
wrResult = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, Inttime, 5, &InttimeSent, 0);
//strobe signal
UCHAR strobe1[] = {0x030001};
ULONG strobeSize1 = strlen((char*)strobe1);
ULONG strobeSent1 = 0;
wr1Result = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, strobe1, 3, &strobeSent1, 0);
//Request spectra
UCHAR Rqspectra[] = {0x09};
ULONG RqSize = strlen((char*)Rqspectra);
ULONG RqSent = 0;
RQResult = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, Rqspectra,1, &RqSent, 0);
//Pixel Values
UCHAR szBuffer[15][512];
UCHAR sz1Buffer[1];
UCHAR tBuffer[1];
ULONG tReadx;
ULONG cbReadx[16];
USHORT newbuf[15][512];
short specbu[7860];
for (int i=0;i<16;i++)
{
if (i<4)
{
sResult = WinUsb_ReadPipe(deviceData.WinusbHandle, 0x86, szBuffer[i], 512, &cbReadx[i], 0);
}
else if (i>=4 && i<15)
{
sResult = WinUsb_ReadPipe(deviceData.WinusbHandle, 0x82, szBuffer[i], 512, &cbReadx[i], 0);
}
else if (i = 15)
{
syResult = WinUsb_ReadPipe(deviceData.WinusbHandle, 0x82, sz1Buffer, 1, &cbReadx[i], 0);
}
}
int pon=0;
for (int k=0;k<15;k++)
{
for (int l=0;l<512;l+=2)
{
newbuf[k][l] = (szBuffer[k][(l+1)]<<8|szBuffer[k][l]);
specbu[pon]= (szBuffer[k][(l+1)]<<8|szBuffer[k][l]);
fprintf(output_file1,"%d\t\n",specbu[pon]);
pon++;
}
}
std::getchar();
CloseDevice(&deviceData);
return 0;
}
My Pch.h
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <winusb.h>
#include <usb.h>
#include "device.h"
My device.h
#include
//
// Device Interface GUID.
// Used by all WinUsb devices that this application talks to.
// Must match "DeviceInterfaceGUIDs" registry value specified in the INF file.
// 390a138c-f867-4538-8fd4-46063b842d2b
//
DEFINE_GUID(GUID_DEVINTERFACE_USBApplication2,
0x390a138c,0xf867,0x4538,0x8f,0xd4,0x46,0x06,0x3b,0x84,0x2d,0x2b);
typedef struct _DEVICE_DATA {
BOOL HandlesOpen;
WINUSB_INTERFACE_HANDLE WinusbHandle;
HANDLE DeviceHandle;
TCHAR DevicePath[MAX_PATH];
}
DEVICE_DATA, *PDEVICE_DATA;
HRESULT
OpenDevice(
_Out_ PDEVICE_DATA DeviceData,
_Out_opt_ PBOOL FailureDeviceNotFound
);
VOID
CloseDevice(
_Inout_ PDEVICE_DATA DeviceData
);
My build log
1>------ Build started: Project: USB Application2, Configuration: Win7 Debug Win32 ------
1> main.cpp
1>main.obj : error LNK2019: unresolved external symbol "long __stdcall OpenDevice(struct _DEVICE_DATA *,int *)" (?OpenDevice##YGJPAU_DEVICE_DATA##PAH#Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "void __stdcall CloseDevice(struct _DEVICE_DATA *)" (?CloseDevice##YGXPAU_DEVICE_DATA###Z) referenced in function _main
1>C:\Users\bel1\Documents\Visual Studio 2012\Projects\USB Application2\Win7Debug\USBApplication2.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Deploy: 0 succeeded, 0 failed, 0 skipped ==========
You will need to add source files (.CPP) into your project that are having implementation of following functions:
OpenDevice
CloseDevice
If you are using a third party library, you need to put the relevant .LIB file into Linker Input of project settings.