函数_wmain中引用未解析的外部符号_RasSetEntryPropertiesW@24

unresolved external symbol _RasSetEntryPropertiesW@24 referenced in function _wmain

本文关键字:外部 RasSetEntryPropertiesW@24 符号 wmain 引用 函数      更新时间:2023-10-16

我正在尝试测试此处描述的函数,以获取与.pbk文件关联的RAS凭据,以检索用户名,密码和预共享密钥等数据。我这样做的原因是因为我丢失了预共享密钥,尽管我将其保存在笔记本电脑上,但我没有找到其他方法来检索它,但也出于教育目的。

这是我尝试运行的代码。(这只是文档中的演示代码,我知道我需要指向我的.pbk文件和条目才能使其执行我想要的操作:

#include <windows.h>
#include "ras.h"
#include <stdio.h>
#include <tchar.h>
#include "strsafe.h"
//#include "pch.h"
#define PHONE_NUMBER_LENGTH 7
#define DEVICE_NAME_LENGTH 5
#define DEVICE_TYPE_LENGTH 5
#define DOMAIN_NAME_LENGTH 9
#define USER_NAME_LENGTH 11
int __cdecl wmain() {
DWORD dwRet = ERROR_SUCCESS;
LPCTSTR lpszEntry = L"RasEntryName";
LPCTSTR lpszPhoneNumber = L"5555555";
LPCTSTR lpszDeviceName = L"Modem";
LPCTSTR lpszDeviceType = RASDT_Modem;
LPCTSTR lpszDomainName = L"RASDomain";
LPCTSTR lpszUserName = L"RASUserName";
/***********************************************************************************************/
// Create a new phone book entry
/***********************************************************************************************/
// Allocate heap memory for the RASENTRY structure
LPRASENTRY lpentry = (LPRASENTRY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RASENTRY));
if (lpentry == NULL) {
wprintf(L"HeapAlloc failed!n");
return 0;
}
// The RASENTRY->dwSize member has to be initialized or the RRAS RasValidateEntryName() and 
// RasSetEntryProperties APIs will fail below.
lpentry->dwSize = sizeof(RASENTRY);
lpentry->dwFramingProtocol = RASFP_Ppp;
lpentry->dwfOptions = 0;
lpentry->dwType = RASFP_Ppp;
dwRet |= StringCchCopyN(lpentry->szLocalPhoneNumber, RAS_MaxPhoneNumber, lpszPhoneNumber, PHONE_NUMBER_LENGTH);
dwRet |= StringCchCopyN(lpentry->szDeviceName, RAS_MaxDeviceName, lpszDeviceName, DEVICE_NAME_LENGTH);
dwRet |= StringCchCopyN(lpentry->szDeviceType, RAS_MaxDeviceType, lpszDeviceType, DEVICE_TYPE_LENGTH);
if (dwRet != ERROR_SUCCESS) {
wprintf(L"RASENTRY structure initilization failed!n");
HeapFree(GetProcessHeap(), 0, lpentry);
return 0;
}
// Validate the new entry's name
dwRet = RasValidateEntryName(NULL, lpszEntry);
if (dwRet != ERROR_SUCCESS) {
wprintf(L"RasValidateEntryName failed: Error = %dn", dwRet);
HeapFree(GetProcessHeap(), 0, lpentry);
return 0;
}
// Create and set the new entry's properties
dwRet = RasSetEntryProperties(NULL, lpszEntry, lpentry, lpentry->dwSize, NULL, 0);
if (dwRet != ERROR_SUCCESS) {
wprintf(L"RasSetEntryProperties failed: Error = %dn", dwRet);
HeapFree(GetProcessHeap(), 0, lpentry);
return 0;
}
/******************************************************************************************/
// Set and get the new entry's credentials
/******************************************************************************************/
// Allocate heap memory for the RASCREDENTIALS structure
LPRASCREDENTIALS lpCred = (LPRASCREDENTIALS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RASCREDENTIALS));
if (lpCred == NULL) {
wprintf(L"HeapAlloc failed!n");
return 0;
}
// The RASCREDENTIALS->dwsize member must be initialized or the RRAS RasSetCredentials() and 
// RasGetCredentials() APIs will fail below
lpCred->dwSize = sizeof(RASCREDENTIALS);
// The entry's credentials must first be set with RasSetCredentials() before they can be 
// retrieved with RasGetCredentials(). The values below are used to set the new entry's credentials.
dwRet |= StringCchCopyN(lpCred->szDomain, DNLEN, lpszDomainName, DOMAIN_NAME_LENGTH);
dwRet |= StringCchCopyN(lpCred->szUserName, UNLEN, lpszUserName, USER_NAME_LENGTH);
if (dwRet != ERROR_SUCCESS) {
wprintf(L"RASCREDENTIALS structure initilization failed!n");
HeapFree(GetProcessHeap(), 0, lpCred);
return 0;
}
// The username, password, and Domain credentials are valid
lpCred->dwMask = RASCM_UserName | RASCM_Password | RASCM_Domain;
// Set the newly created entry's credentials
dwRet = RasSetCredentials(NULL, lpszEntry, lpCred, FALSE);
// The same RASCREDENTIALS structure is used to 'set' and 'get' the credentials. Therefore, zero out 
// its values. (this proves RasGetCredentials works below!) 
dwRet |= StringCchCopyN(lpCred->szDomain, DNLEN, L"", 0);
dwRet |= StringCchCopyN(lpCred->szUserName, UNLEN, L"", 0);
dwRet |= StringCchCopyN(lpCred->szPassword, UNLEN, L"", 0);
if (dwRet != ERROR_SUCCESS) {
wprintf(L"RASCREDENTIALS structure reset failed!n");
HeapFree(GetProcessHeap(), 0, lpCred);
HeapFree(GetProcessHeap(), 0, lpentry);
return 0;
}
// Grab the newly created entry's credentials
dwRet = RasGetCredentials(NULL, lpszEntry, lpCred);
if (dwRet == ERROR_SUCCESS) {
wprintf(L"The following credentials were retrieved for the entry: %sntUser name: %sntPassword: %sntDomain: %sn", lpszEntry, lpCred->szUserName, lpCred->szPassword, lpCred->szDomain);
}
else {
wprintf(L"RasValidateEntryName failed: Error = %dn", dwRet);
}
// Clean up: delete the new entry
dwRet = RasDeleteEntry(NULL, lpszEntry);
if (dwRet != ERROR_SUCCESS) {
wprintf(L"RasDeleteEntry failed: Error = %dn", dwRet);
}
HeapFree(GetProcessHeap(), 0, lpentry);
HeapFree(GetProcessHeap(), 0, lpCred);
return 0;
}

但是,我无法在Visual Studio 2017中编译上面的代码。以下是错误日志:

RasCredentials.obj : error LNK2019: unresolved external symbol _RasSetEntryPropertiesW@24 referenced in function _wmain
RasCredentials.obj : error LNK2019: unresolved external symbol _RasDeleteEntryW@8 referenced in function _wmain
RasCredentials.obj : error LNK2019: unresolved external symbol _RasValidateEntryNameW@8 referenced in function _wmain
RasCredentials.obj : error LNK2019: unresolved external symbol _RasGetCredentialsW@12 referenced in function _wmain
RasCredentials.obj : error LNK2019: unresolved external symbol _RasSetCredentialsW@16 referenced in function _wmain

就像编译器看不到RAS库一样,即使我包含了ras.h头文件。

我通过将Rasapi32.lib添加到依赖项中解决了这个问题。我通过转到项目 ->(项目名称(属性 ->链接器 ->输入 ->其他依赖项并添加Rasapi32.lib来做到这一点。

但是,现在我遇到了一个问题,即密码显示为一组*而不是明文,我想我需要的预共享密钥也是如此。