Skip to content

Commit

Permalink
Merge pull request #12550 from unknownbrackets/win-long-path
Browse files Browse the repository at this point in the history
Attempt support for Windows long paths
  • Loading branch information
hrydgard authored Jan 11, 2020
2 parents 42bfcc7 + 9b745d4 commit 52156ec
Show file tree
Hide file tree
Showing 17 changed files with 270 additions and 160 deletions.
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 @@ -313,10 +313,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

0 comments on commit 52156ec

Please sign in to comment.