Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt support for Windows long paths #12550

Merged
merged 9 commits into from
Jan 11, 2020
23 changes: 17 additions & 6 deletions Common/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,12 +792,23 @@ const std::string &GetExeDirectory()

if (ExePath.empty()) {
#ifdef _WIN32
TCHAR program_path[4096] = {0};
GetModuleFileName(NULL, program_path, ARRAY_SIZE(program_path) - 1);
program_path[ARRAY_SIZE(program_path) - 1] = '\0';
TCHAR *last_slash = _tcsrchr(program_path, '\\');
if (last_slash != NULL)
*(last_slash + 1) = '\0';
#ifdef UNICODE
std::wstring program_path;
#else
std::string program_path;
#endif
size_t sz;
do {
program_path.resize(program_path.size() + MAX_PATH);
// On failure, this will return the same value as passed in, but success will always be one lower.
sz = GetModuleFileName(nullptr, &program_path[0], (DWORD)program_path.size());
} while (sz >= program_path.size());

TCHAR *last_slash = _tcsrchr(&program_path[0], '\\');
if (last_slash != nullptr)
program_path.resize(last_slash - &program_path[0] + 1);
else
program_path.resize(sz);
#ifdef UNICODE
ExePath = ConvertWStringToUTF8(program_path);
#else
Expand Down
14 changes: 11 additions & 3 deletions Core/PSPLoaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,18 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {

static std::string NormalizePath(const std::string &path) {
#ifdef _WIN32
wchar_t buf[512] = {0};
std::wstring wpath = ConvertUTF8ToWString(path);
if (GetFullPathName(wpath.c_str(), (int)ARRAY_SIZE(buf) - 1, buf, NULL) == 0)
return "";
std::wstring buf;
buf.resize(512);
size_t sz = GetFullPathName(wpath.c_str(), (DWORD)buf.size(), &buf[0], nullptr);
if (sz != 0 && sz < buf.size()) {
buf.resize(sz);
} else if (sz > buf.size()) {
buf.resize(sz);
sz = GetFullPathName(wpath.c_str(), (DWORD)buf.size(), &buf[0], nullptr);
// This should truncate off the null terminator.
buf.resize(sz);
}
return ConvertWStringToUTF8(buf);
#else
char buf[PATH_MAX + 1];
Expand Down
11 changes: 7 additions & 4 deletions Core/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <ShlObj.h>
#include <string>
#include <codecvt>
#if !PPSSPP_PLATFORM(UWP)
#include "Windows/W32Util/ShellUtil.h"
#endif
#endif

#include <thread>
Expand Down Expand Up @@ -560,14 +563,14 @@ void InitSysDirectories() {
// We set g_Config.memStickDirectory outside.

#else
wchar_t myDocumentsPath[MAX_PATH];
const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath);
const std::string myDocsPath = ConvertWStringToUTF8(myDocumentsPath) + "/PPSSPP/";
// Caller sets this to the Documents folder.
const std::string rootMyDocsPath = g_Config.internalDataDirectory;
const std::string myDocsPath = rootMyDocsPath + "/PPSSPP/";
const std::string installedFile = path + "installed.txt";
const bool installed = File::Exists(installedFile);

// If installed.txt exists(and we can determine the Documents directory)
if (installed && (result == S_OK)) {
if (installed && rootMyDocsPath.size() > 0) {
#if defined(_WIN32) && defined(__MINGW32__)
std::ifstream inputFile(installedFile);
#else
Expand Down
24 changes: 9 additions & 15 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,13 +743,12 @@ void GameSettingsScreen::CreateViews() {
SavePathInOtherChoice = systemSettings->Add(new CheckBox(&otherinstalled_, sy->T("Save path in installed.txt", "Save path in installed.txt")));
SavePathInOtherChoice->SetEnabled(false);
SavePathInOtherChoice->OnClick.Handle(this, &GameSettingsScreen::OnSavePathOther);
wchar_t myDocumentsPath[MAX_PATH];
const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath);
const bool myDocsExists = W32Util::UserDocumentsPath().size() != 0;
const std::string PPSSPPpath = File::GetExeDirectory();
const std::string installedFile = PPSSPPpath + "installed.txt";
installed_ = File::Exists(installedFile);
otherinstalled_ = false;
if (!installed_ && result == S_OK) {
if (!installed_ && myDocsExists) {
if (File::CreateEmptyFile(PPSSPPpath + "installedTEMP.txt")) {
// Disable the setting whether cannot create & delete file
if (!(File::Delete(PPSSPPpath + "installedTEMP.txt")))
Expand All @@ -759,7 +758,7 @@ void GameSettingsScreen::CreateViews() {
} else
SavePathInMyDocumentChoice->SetEnabled(false);
} else {
if (installed_ && (result == S_OK)) {
if (installed_ && myDocsExists) {
#ifdef _MSC_VER
std::ifstream inputFile(ConvertUTF8ToWString(installedFile));
#else
Expand All @@ -779,8 +778,9 @@ void GameSettingsScreen::CreateViews() {
}
}
inputFile.close();
} else if (result != S_OK)
} else if (!myDocsExists) {
SavePathInMyDocumentChoice->SetEnabled(false);
}
}
#endif

Expand Down Expand Up @@ -925,26 +925,20 @@ UI::EventReturn GameSettingsScreen::OnSavePathMydoc(UI::EventParams &e) {
File::Delete(PPSSPPpath + "installed.txt");
File::CreateEmptyFile(PPSSPPpath + "installed.txt");
otherinstalled_ = false;
wchar_t myDocumentsPath[MAX_PATH];
const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath);
const std::string myDocsPath = ConvertWStringToUTF8(myDocumentsPath) + "/PPSSPP/";
const std::string myDocsPath = W32Util::UserDocumentsPath() + "/PPSSPP/";
g_Config.memStickDirectory = myDocsPath;
}
else if (installed_) {
} else if (installed_) {
File::Delete(PPSSPPpath + "installed.txt");
installed_ = false;
g_Config.memStickDirectory = PPSSPPpath + "memstick/";
}
else {
} else {
std::ofstream myfile;
myfile.open(PPSSPPpath + "installed.txt");
if (myfile.is_open()){
myfile.close();
}

wchar_t myDocumentsPath[MAX_PATH];
const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath);
const std::string myDocsPath = ConvertWStringToUTF8(myDocumentsPath) + "/PPSSPP/";
const std::string myDocsPath = W32Util::UserDocumentsPath() + "/PPSSPP/";
g_Config.memStickDirectory = myDocsPath;
installed_ = true;
}
Expand Down
10 changes: 8 additions & 2 deletions UI/MainScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,14 @@ static bool IsTempPath(const std::string &str) {
// Normalize slashes.
item = ReplaceAll(str, "/", "\\");

wchar_t tempPath[MAX_PATH];
GetTempPath(MAX_PATH, tempPath);
std::wstring tempPath(MAX_PATH, '\0');
size_t sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
if (sz >= tempPath.size()) {
tempPath.resize(sz);
sz = GetTempPath((DWORD)tempPath.size(), &tempPath[0]);
}
// Need to resize off the null terminator either way.
tempPath.resize(sz);
if (testPath(ConvertWStringToUTF8(tempPath)))
return true;
#endif
Expand Down
53 changes: 19 additions & 34 deletions Windows/Debugger/CtrlDisAsmView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Core/MemMap.h"
#include "Core/MIPS/JitCommon/JitCommon.h"
#include "Windows/W32Util/Misc.h"
#include "Windows/W32Util/ShellUtil.h"
#include "Windows/MainWindow.h"
#include "Windows/InputBox.h"

Expand Down Expand Up @@ -1323,47 +1324,31 @@ std::string CtrlDisAsmView::disassembleRange(u32 start, u32 size)
return result;
}

void CtrlDisAsmView::disassembleToFile()
{
wchar_t fileName[MAX_PATH];
u32 size;

void CtrlDisAsmView::disassembleToFile() {
// get size
if (executeExpressionWindow(wnd,debugger,size) == false) return;
if (size == 0 || size > 10*1024*1024)
{
u32 size;
if (executeExpressionWindow(wnd,debugger,size) == false)
return;
if (size == 0 || size > 10*1024*1024) {
MessageBox(wnd,L"Invalid size!",L"Error",MB_OK);
return;
}

// get file name
OPENFILENAME ofn;
ZeroMemory( &ofn , sizeof( ofn));
ofn.lStructSize = sizeof ( ofn );
ofn.hwndOwner = NULL ;
ofn.lpstrFile = fileName ;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof( fileName );
ofn.lpstrFilter = L"All Files\0*.*\0\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL ;
ofn.nMaxFileTitle = 0 ;
ofn.lpstrInitialDir = NULL ;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_OVERWRITEPROMPT;

if (GetSaveFileName(&ofn) == false) return;

FILE* output = _wfopen(fileName, L"wb");
if (output == NULL) {
MessageBox(wnd,L"Could not open file!",L"Error",MB_OK);
return;
}
std::string filename;
if (W32Util::BrowseForFileName(false, nullptr, L"Save Disassembly As...", nullptr, L"All Files\0*.*\0\0", nullptr, filename)) {
std::wstring fileName = ConvertUTF8ToWString(filename);
FILE *output = _wfopen(fileName.c_str(), L"wb");
if (output == nullptr) {
MessageBox(wnd, L"Could not open file!", L"Error", MB_OK);
return;
}

std::string disassembly = disassembleRange(curAddress,size);
fprintf(output,"%s",disassembly.c_str());
std::string disassembly = disassembleRange(curAddress, size);
fprintf(output, "%s", disassembly.c_str());

fclose(output);
MessageBox(wnd,L"Finished!",L"Done",MB_OK);
fclose(output);
MessageBox(wnd, L"Finished!", L"Done", MB_OK);
}
}

void CtrlDisAsmView::getOpcodeText(u32 address, char* dest, int bufsize)
Expand Down
50 changes: 30 additions & 20 deletions Windows/Debugger/DumpMemoryWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
#include "DumpMemoryWindow.h"
#include "../resource.h"
#include <stdio.h>
#include <algorithm>
#include <cstdio>
#include "util/text/utf8.h"
#include "Core/Core.h"
#include "Core/MemMap.h"
#include "Windows/Debugger/DumpMemoryWindow.h"
#include "Windows/resource.h"
#include "Windows/W32Util/ShellUtil.h"
#include "Core/Core.h"

DumpMemoryWindow* DumpMemoryWindow::bp;

void DumpMemoryWindow::HandleBrowseClick(HWND hwnd) {
std::wstring buffer;
HWND filenameWnd = GetDlgItem(hwnd, IDC_DUMP_FILENAME);
buffer.resize(GetWindowTextLengthW(filenameWnd) + 1);
GetWindowTextW(filenameWnd, &buffer[0], (int)buffer.size());
std::string fn = ConvertWStringToUTF8(buffer);

bool result = W32Util::BrowseForFileName(false, hwnd, L"Select filename", NULL, NULL, NULL, fn);
if (result) {
filenameChosen_ = true;
buffer = ConvertUTF8ToWString(fn);
SetWindowTextW(filenameWnd, buffer.c_str());
}
}

INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
Expand Down Expand Up @@ -53,16 +70,7 @@ INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam,
switch (HIWORD(wParam))
{
case BN_CLICKED:
char str[MAX_PATH];
GetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),str,MAX_PATH);
std::string fn = str;

bool result = W32Util::BrowseForFileName(false, hwnd, L"Select filename", NULL,NULL,NULL,fn);
if (result)
{
bp->filenameChosen = true;
SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),fn.c_str());
}
bp->HandleBrowseClick(hwnd);
break;
}
break;
Expand All @@ -73,10 +81,10 @@ INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam,
if (!PSP_IsInited())
break;

FILE* output = fopen(bp->fileName,"wb");
FILE *output = _wfopen(bp->fileName_.c_str(), L"wb");
if (output == NULL) {
char errorMessage[2048];
snprintf(errorMessage, sizeof(errorMessage), "Could not open file \"%s\".",bp->fileName);
snprintf(errorMessage, sizeof(errorMessage), "Could not open file \"%S\".", bp->fileName_.c_str());
MessageBoxA(hwnd,errorMessage,"Error",MB_OK);
break;
}
Expand Down Expand Up @@ -140,8 +148,10 @@ bool DumpMemoryWindow::fetchDialogData(HWND hwnd)
}

// get filename
GetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),fileName,MAX_PATH);
if (strlen(fileName) == 0) return false;
fileName_.resize(GetWindowTextLengthW(GetDlgItem(hwnd, IDC_DUMP_FILENAME)) + 1);
GetWindowTextW(GetDlgItem(hwnd, IDC_DUMP_FILENAME), &fileName_[0], (int)fileName_.size());
if (fileName_.size() == 0)
return false;

// now check if data makes sense...
bool invalidSize = false;
Expand Down Expand Up @@ -190,7 +200,7 @@ void DumpMemoryWindow::changeMode(HWND hwnd, Mode newMode)
EnableWindow(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),TRUE);
EnableWindow(GetDlgItem(hwnd,IDC_DUMP_SIZE),TRUE);

if (filenameChosen == false)
if (filenameChosen_ == false)
SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),"Custom.dump");
} else {
u32 start, size;
Expand Down Expand Up @@ -223,7 +233,7 @@ void DumpMemoryWindow::changeMode(HWND hwnd, Mode newMode)
SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_SIZE),buffer);
EnableWindow(GetDlgItem(hwnd,IDC_DUMP_SIZE),FALSE);

if (filenameChosen == false)
if (filenameChosen_ == false)
SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),defaultFileName);
}
}
Expand Down
8 changes: 5 additions & 3 deletions Windows/Debugger/DumpMemoryWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ class DumpMemoryWindow

HWND parentHwnd;
DebugInterface* cpu;
bool filenameChosen;
bool filenameChosen_;
Mode selectedMode;

u32 start;
u32 size;
char fileName[MAX_PATH];
std::wstring fileName_;

static DumpMemoryWindow* bp;
void changeMode(HWND hwnd, Mode newMode);
bool fetchDialogData(HWND hwnd);
void HandleBrowseClick(HWND hwnd);

public:
DumpMemoryWindow(HWND parent, DebugInterface* cpu): cpu(cpu)
{
parentHwnd = parent;
filenameChosen = false;
filenameChosen_ = false;
selectedMode = MODE_RAM;
};

Expand Down
3 changes: 2 additions & 1 deletion Windows/PPSSPP.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- Should really use True/PM (per-monitor) here but as we are XP-compatible, we don't have access to the headers. -->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>
Loading