diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7046e38..fa91121 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,36 +14,30 @@ on: jobs: build: - strategy: - matrix: - toolchain: ["windows-static-x64"] # "linux-x64", - runs-on: ubuntu-latest - container: dockcross/${{ matrix.toolchain }}:latest + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} steps: - - - name: Checkout - uses: actions/checkout@v3 + - uses: actions/checkout@v5 + - uses: msys2/setup-msys2@v2 with: - fetch-depth: 0 - - - name: fix ownership, add dependencies and fetch - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - sudo apt-get install --assume-yes p7zip-full - git fetch --prune + msystem: UCRT64 + update: true + install: git mingw-w64-ucrt-x86_64-gcc make p7zip - name: Compile project run: | make clean all - 7z a -t7z ${{ github.event.repository.name }}-${{ matrix.toolchain }}.7z README.md "${{ github.event.repository.name }}*" + 7z a -t7z ${{ github.event.repository.name }}-w64.7z README.md "${{ github.event.repository.name }}*" - name: Upload artifacts if: ${{ success() }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ github.event.repository.name }} path: | - ${{ github.event.repository.name }}-${{ matrix.toolchain }}.7z + ${{ github.event.repository.name }}-w64.7z release: runs-on: ubuntu-latest @@ -51,13 +45,13 @@ jobs: steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - run: | git config --global --add safe.directory "$GITHUB_WORKSPACE" git fetch --prune --unshallow - name: Download all artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v5 - name: list run: | @@ -70,4 +64,4 @@ jobs: automatic_release_tag: "windows" title: "Latest automated build" files: | - ${{ github.event.repository.name }}/*.7z + ${{ github.event.repository.name }}*.7z diff --git a/Makefile b/Makefile index bd34770..2ece687 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ udpbd-server: $(OBJS) g++ -static -static-libgcc -static-libstdc++ -o $@ $^ -lws2_32 main.o: main.cpp - g++ -Wall -c -Os main.cpp -o main.o + g++ -fno-inline -Wall -c -Os main.cpp -o main.o all: $(BIN) diff --git a/README.md b/README.md new file mode 100644 index 0000000..ab87423 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# UDPBD Server + +By Rick Gaiser + +windows version by Alex Parrado + +brought to github by El_isra + +## How to compile with MSYS2 for windows + +Download and install [MSYS2](https://www.msys2.org/). +Open a MSYS2 UCRT64 terminal. + +```bash +pacman -Syuu +pacman --needed -S git make mingw-w64-ucrt-x86_64-gcc + +git clone -b windows https://github.com/israpps/udpbd-server.git +cd ./udpbd-server/ +make +``` +Upon success udpbd-server.exe will be compiled. + diff --git a/main.cpp b/main.cpp index b4d50e3..3fa5874 100644 --- a/main.cpp +++ b/main.cpp @@ -11,26 +11,25 @@ #include #include #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -#include -#include -#include -#include #include -#include -#include - -#ifndef _off64_t -#define _off64_t off64_t -#endif - -#else - +#include #endif #include "udpbd.h" #define BUFLEN 2048 +#if defined(__APPLE__) || defined( __FreeBSD__) +#include +#include +#define lseek64 lseek +#define loff_t off_t +#endif + +#if defined(__APPLE__) +#define _DARWIN_USE_64_BIT_INODE 1 +#endif + using namespace std; /* @@ -70,7 +69,7 @@ class CBlockDevice printf("Error %lu attempting to dismount volume, error code\n", err); } - // Get the size of the file + // Get disk geometry for sector size DWORD junk = 0; DISK_GEOMETRY pdg; BOOL bResult = DeviceIoControl(_fp, // device to be queried @@ -82,16 +81,50 @@ class CBlockDevice if (bResult) { - sector_offset = 0; - _fsize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder * - (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector; - sector_size = pdg.BytesPerSector; + sector_size = pdg.BytesPerSector; // Use actual sector size from disk + } + else + { + sector_size = 512; // Fallback to standard sector size + printf("Warning: Could not get disk geometry, using default sector size 512\n"); + } + + // Get the volume/partition size + PARTITION_INFORMATION_EX partInfo; + + bResult = DeviceIoControl(_fp, // device to be queried + IOCTL_DISK_GET_PARTITION_INFO_EX, // operation to perform + NULL, 0, // no input buffer + &partInfo, sizeof(partInfo), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED)NULL); + + if (bResult) + { + _fsize = partInfo.PartitionLength.QuadPart; + } + else + { + // Fallback to disk length info + GET_LENGTH_INFORMATION lengthInfo; + bResult = DeviceIoControl(_fp, // device to be queried + IOCTL_DISK_GET_LENGTH_INFO, // operation to perform + NULL, 0, // no input buffer + &lengthInfo, sizeof(lengthInfo), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED)NULL); + if (bResult) + _fsize = lengthInfo.Length.QuadPart; + } + + if (bResult) + { printf("Opened '%s' as Block Device\n", sFileName); printf(" - %s\n", _read_only ? "read-only" : "read/write"); - printf(" - size = %ldMB / %ldMiB, sector size = %ld\n", _fsize / (1000 * 1000), _fsize / (1024 * 1024), sector_size); + printf(" - size = %lldMB / %lldMiB, sector size = %lld\n", _fsize / (1000 * 1000), _fsize / (1024 * 1024), sector_size); } else - printf("Error: %lu\n", GetLastError()); + printf("Error getting volume/disk size: %lu\n", GetLastError()); fflush(stdout); } @@ -134,14 +167,14 @@ class CBlockDevice // If this call has remaining bytes, store them for next call if (remainder != 0) { - memcpy(sector_buffer, data + size, sector_size - remainder); + memcpy(sector_buffer, (char *)data + size, sector_size - remainder); sector_offset = (sector_size - remainder); } else sector_offset = 0; } else - printf("Error reading sectors: %lu\n", GetLastError()); + printf("Error reading sectors: %ld\n", GetLastError()); } // TODO: This method is not optimized, nonetheless in game write operations are not critical @@ -165,7 +198,7 @@ class CBlockDevice ret = WriteFile(_fp, sector_buffer, aux_size, &rv, NULL); // printf("write %ld\n", size); if (ret == 0) - printf("write error %ld != %ld,%lu\n", rv, size, GetLastError()); + printf("write error %ld != %llu,%lu\n", rv, size, GetLastError()); } uint32_t get_sector_size() { return sector_size; } @@ -187,7 +220,7 @@ class CBlockDevice class CUDPBDServer { public: - CUDPBDServer(class CBlockDevice &bd) : _bd(bd), _block_shift(0) + CUDPBDServer(class CBlockDevice &bd) : _bd(bd), _block_shift(0), _total_read(0), _total_write(0) { set_block_shift(5); // 128b blocks struct sockaddr_in si_me; @@ -219,7 +252,7 @@ class CUDPBDServer si_me.sin_family = AF_INET; si_me.sin_port = htons(UDPBD_PORT); si_me.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(s, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) + if (::bind(s, (struct sockaddr*)&si_me, sizeof(si_me)) == -1) { throw runtime_error("bind"); } @@ -276,12 +309,18 @@ class CUDPBDServer } private: + void print_stats() + { + printf("Total read: %llu KiB, total write: %llu KiB\r", _total_read/1024, _total_write/1024); + fflush(stdout); + } + void set_block_shift(uint32_t shift) { if (shift != _block_shift) { - _block_shift = shift; - _block_size = 1 << (_block_shift + 2); + _block_shift = shift; + _block_size = 1 << (_block_shift + 2); _blocks_per_packet = RDMA_MAX_PAYLOAD / _block_size; _blocks_per_sector = _bd.get_sector_size() / _block_size; printf("Block size changed to %d\n", _block_size); @@ -319,7 +358,8 @@ class CUDPBDServer char str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &si_other.sin_addr, str, INET_ADDRSTRLEN); - printf("UDPBD_CMD_INFO from %s\n", str); + printf("UDPBD_CMD_INFO from %s \n", str); + print_stats(); // Reply header reply.hdr.cmd = UDPBD_CMD_INFO_REPLY; @@ -332,7 +372,7 @@ class CUDPBDServer // Send packet to ps2 if (sendto(s, (char *)&reply, sizeof(reply), 0, (struct sockaddr *)&si_other, sizeof(si_other)) == -1) { - throw runtime_error("sendto"); + printf("Error calling sendto in handle_cmd_info\nReady for Retry\n"); } } @@ -340,7 +380,7 @@ class CUDPBDServer { struct SUDPBDv2_RDMA reply; - // printf("UDPBD_CMD_READ(cmdId=%d, startSector=%d, sectorCount=%d)\n", request->hdr.cmdid, request->sector_nr, request->sector_count); + printf("UDPBD_CMD_READ(cmdId=%d, startSector=%d, sectorCount=%d)\n", request->hdr.cmdid, request->sector_nr, request->sector_count); // Optimize RDMA block size for number of sectors set_block_shift_sectors(request->sector_count); @@ -353,6 +393,9 @@ class CUDPBDServer uint32_t blocks_left = request->sector_count * _blocks_per_sector; + _total_read += blocks_left * _block_size; + print_stats(); + _bd.seek(request->sector_nr); _bd.clear_sector_offset(); @@ -368,7 +411,7 @@ class CUDPBDServer // Send packet to ps2 if (sendto(s, (char *)&reply, sizeof(struct SUDPBDv2_Header) + 4 + (reply.bt.block_count * _block_size), 0, (struct sockaddr *)&si_other, sizeof(si_other)) == -1) { - throw runtime_error("sendto"); + throw runtime_error("Error calling sendto in handle_cmd_read"); } reply.hdr.cmdpkt++; } @@ -380,6 +423,9 @@ class CUDPBDServer _bd.seek(request->sector_nr); _write_size_left = request->sector_count * 512; + + _total_write += _write_size_left; + print_stats(); } void handle_cmd_write_rdma(struct sockaddr_in &si_other, struct SUDPBDv2_RDMA *request) @@ -394,15 +440,15 @@ class CUDPBDServer struct SUDPBDv2_WriteDone reply; // Reply header - reply.hdr.cmd = UDPBD_CMD_WRITE_DONE; - reply.hdr.cmdid = request->hdr.cmdid; - reply.hdr.cmdpkt = request->hdr.cmdid + 1; - reply.result = 0; + reply.hdr.cmd = UDPBD_CMD_WRITE_DONE; + reply.hdr.cmdid = request->hdr.cmdid; + reply.hdr.cmdpkt = request->hdr.cmdid + 1; + reply.result = 0; // Send packet to ps2 if (sendto(s, (char *)&reply, sizeof(reply), 0, (struct sockaddr *)&si_other, sizeof(si_other)) == -1) { - throw runtime_error("sendto"); + throw runtime_error("Error calling sendto in handle_cmd_write_rdma"); } } } @@ -414,6 +460,9 @@ class CUDPBDServer uint32_t _blocks_per_sector; int s; + uint64_t _total_read; + uint64_t _total_write; + uint32_t _write_size_left; };