|
4 | 4 | #include <winpr/file.h>
|
5 | 5 | #include <winpr/windows.h>
|
6 | 6 |
|
| 7 | +static const char* get_dir(char* filename, size_t len) |
| 8 | +{ |
| 9 | +#if defined(WIN32) |
| 10 | + if ((len == 0) || (strnlen_s(filename, len) == len)) |
| 11 | + return NULL; |
| 12 | + char* ptr = strrchr(filename, '\\'); |
| 13 | +#else |
| 14 | + if ((len == 0) || (strnlen(filename, len) == len)) |
| 15 | + return NULL; |
| 16 | + char* ptr = strrchr(filename, '/'); |
| 17 | +#endif |
| 18 | + if (!ptr) |
| 19 | + return NULL; |
| 20 | + *ptr = '\0'; |
| 21 | + return filename; |
| 22 | +} |
| 23 | + |
| 24 | +static BOOL get_tmp(char* path, size_t len) |
| 25 | +{ |
| 26 | +#if defined(WIN32) |
| 27 | + const char template[] = "tmpdir.XXXXXX"; |
| 28 | + strncmp(path, template, strnlen_s(template, len) + 1); |
| 29 | + if (!mktemp_s(path)) |
| 30 | + return FALSE; |
| 31 | + strcat_s(path, len, "\\testfile"); |
| 32 | + if (strnlen_s(path, len) + 10 > len) |
| 33 | + return FALSE; |
| 34 | +#else |
| 35 | + const char template[] = "/tmp/tmpdir.XXXXXX"; |
| 36 | + if (!strncpy(path, template, strnlen(template, len) + 1)) |
| 37 | + return FALSE; |
| 38 | + if (!mkdtemp(path)) |
| 39 | + return FALSE; |
| 40 | + if (strnlen(path, len) + 10 > len) |
| 41 | + return FALSE; |
| 42 | + strcat(path, "/testfile"); |
| 43 | +#endif |
| 44 | + return TRUE; |
| 45 | +} |
| 46 | + |
| 47 | +static BOOL test_write(const char* filename, const char* data, size_t datalen) |
| 48 | +{ |
| 49 | + BOOL rc = FALSE; |
| 50 | + |
| 51 | + WINPR_ASSERT(filename); |
| 52 | + WINPR_ASSERT(data); |
| 53 | + WINPR_ASSERT(datalen > 0); |
| 54 | + |
| 55 | + HANDLE hdl = |
| 56 | + CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); |
| 57 | + if (!hdl || (hdl == INVALID_HANDLE_VALUE)) |
| 58 | + goto fail; |
| 59 | + |
| 60 | + DWORD written = 0; |
| 61 | + if (!WriteFile(hdl, data, datalen, &written, NULL)) |
| 62 | + goto fail; |
| 63 | + if (written != datalen) |
| 64 | + goto fail; |
| 65 | + |
| 66 | + if (!FlushFileBuffers(hdl)) |
| 67 | + goto fail; |
| 68 | + |
| 69 | + rc = TRUE; |
| 70 | +fail: |
| 71 | + CloseHandle(hdl); |
| 72 | + return rc; |
| 73 | +} |
| 74 | + |
| 75 | +static BOOL test_read(const char* filename, const char* data, size_t datalen) |
| 76 | +{ |
| 77 | + BOOL rc = FALSE; |
| 78 | + |
| 79 | + WINPR_ASSERT(filename); |
| 80 | + WINPR_ASSERT(data); |
| 81 | + WINPR_ASSERT(datalen > 0); |
| 82 | + |
| 83 | + char* cmp = calloc(datalen + 1, sizeof(char)); |
| 84 | + HANDLE hdl = |
| 85 | + CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
| 86 | + if (!hdl || (hdl == INVALID_HANDLE_VALUE) || !cmp) |
| 87 | + goto fail; |
| 88 | + |
| 89 | + DWORD read = 0; |
| 90 | + if (!ReadFile(hdl, cmp, datalen, &read, NULL)) |
| 91 | + goto fail; |
| 92 | + if (read != datalen) |
| 93 | + goto fail; |
| 94 | + if (memcmp(data, cmp, datalen) != 0) |
| 95 | + goto fail; |
| 96 | + if (FlushFileBuffers(hdl)) |
| 97 | + goto fail; |
| 98 | + |
| 99 | + rc = TRUE; |
| 100 | +fail: |
| 101 | + free(cmp); |
| 102 | + CloseHandle(hdl); |
| 103 | + return rc; |
| 104 | +} |
| 105 | + |
7 | 106 | int TestFileWriteFile(int argc, char* argv[])
|
8 | 107 | {
|
9 |
| - return 0; |
| 108 | + const char data[] = "sometesttext\nanother line\r\ngogogo\r\tfoo\t\r\n\r"; |
| 109 | + char filename[MAX_PATH] = { 0 }; |
| 110 | + |
| 111 | + int rc = -1; |
| 112 | + if (!get_tmp(filename, sizeof(filename))) |
| 113 | + goto fail; |
| 114 | + |
| 115 | + if (!test_write(filename, data, sizeof(data))) |
| 116 | + goto fail; |
| 117 | + |
| 118 | + if (!test_read(filename, data, sizeof(data))) |
| 119 | + goto fail; |
| 120 | + |
| 121 | + rc = 0; |
| 122 | +fail: |
| 123 | + if (!DeleteFile(filename)) |
| 124 | + rc = -2; |
| 125 | + |
| 126 | + const char* d = get_dir(filename, sizeof(filename)); |
| 127 | + if (d) |
| 128 | + { |
| 129 | + if (!RemoveDirectory(d)) |
| 130 | + rc = -3; |
| 131 | + } |
| 132 | + return rc; |
10 | 133 | }
|
0 commit comments