C++ 未解析外部符号_RasSetEntryPropertiesW@24在函数\u wmain中引用

C++ 未解析外部符号_RasSetEntryPropertiesW@24在函数\u wmain中引用,c++,credentials,ras,C++,Credentials,Ras,我正在尝试测试所描述的函数,以获取与.pbk文件关联的RAS凭据,从而检索用户名、密码和预共享密钥等数据。我这样做的原因是我丢失了我的预共享密钥,虽然我把它保存在笔记本电脑上,但我没有找到其他方法来检索它,而且也是出于教育目的 这是我试图运行的代码。(这只是文档中的一段演示代码,我知道我需要指向我的.pbk文件和条目,以使其实现我想要的功能: #include <windows.h> #include "ras.h" #include <stdio.h> #include

我正在尝试测试所描述的函数,以获取与
.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 = %d\n", 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 = %d\n", 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: %s\n\tUser name: %s\n\tPassword: %s\n\tDomain: %s\n", lpszEntry, lpCred->szUserName, lpCred->szPassword, lpCred->szDomain);
    }
    else {
        wprintf(L"RasValidateEntryName failed: Error = %d\n", dwRet);
    }

    // Clean up: delete the new entry
    dwRet = RasDeleteEntry(NULL, lpszEntry);
    if (dwRet != ERROR_SUCCESS) {
        wprintf(L"RasDeleteEntry failed: Error = %d\n", dwRet);
    }

    HeapFree(GetProcessHeap(), 0, lpentry);
    HeapFree(GetProcessHeap(), 0, lpCred);
    return 0;
}

就好像编译器没有看到RAS库,即使我包含了
RAS.h
头文件。

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


但是,现在我有一个问题,密码显示为一组
*
,而不是纯文本,我想我需要的预共享密钥也是这样。

“密码显示为一组
*
,而不是纯文本”-应该是这样的:“RasGetCredentials不返回实际密码。相反,RASCREDENTIALS结构的szPassword成员包含保存密码的句柄。在后续调用RasSetCredentials和RasDial时,用此句柄替换保存的密码。当显示此句柄时,RasDial检索并使用保存的密码…”..如果dwMask成员指定凭据应使用预共享密钥,则szPassword成员包含预共享密钥。如果RASCREDENTIALS结构与RasGetCredentials一起使用,则返回的值是前一段中描述的预共享密钥的句柄。“据我所知,没有”官方"取出预共享密钥的方法?因为,在我看来,我可以使用句柄设置另一个条目的预共享密钥,但我无法打印出预共享密钥?我想有一些黑客方法可以做到这一点,比如在调用RasSetCredentials时将pbk文件定位在网络上的另一台机器上,或者使用某种工具读取进程内存和fet我想确定我是否正确地得到了密码。这是正确的吗?对不起,我不太熟悉C++和句柄的概念:“没有”官方“的方式来拔出预共享密钥吗?”-正确。密码和预共享密钥私下存储在RAS条目中,您无法手动提取实际值。
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