| 212 | return 1 |
| 213 | |
| 214 | def _CreateFile(ql: Qiling, address: int, params): |
| 215 | s_lpFileName = params["lpFileName"] |
| 216 | dwDesiredAccess = params["dwDesiredAccess"] |
| 217 | # dwShareMode = params["dwShareMode"] |
| 218 | # lpSecurityAttributes = params["lpSecurityAttributes"] |
| 219 | |
| 220 | # Handle Creation Disposition. I.e. how to respond |
| 221 | # when a file either exists or doesn't |
| 222 | # See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea |
| 223 | dwCreationDisposition = params["dwCreationDisposition"] |
| 224 | |
| 225 | # dwFlagsAndAttributes = params["dwFlagsAndAttributes"] |
| 226 | # hTemplateFile = params["hTemplateFile"] |
| 227 | |
| 228 | # access mask DesiredAccess |
| 229 | perm_write = dwDesiredAccess & (GENERIC_WRITE | FILE_WRITE_DATA) |
| 230 | perm_read = dwDesiredAccess & (GENERIC_READ | FILE_READ_DATA) |
| 231 | |
| 232 | # TODO: unused |
| 233 | perm_exec = dwDesiredAccess & (GENERIC_EXECUTE | FILE_EXECUTE) |
| 234 | |
| 235 | # only open file if it exists. error otherwise |
| 236 | open_existing = ( |
| 237 | (dwCreationDisposition == OPEN_EXISTING) or |
| 238 | (dwCreationDisposition == TRUNCATE_EXISTING ) |
| 239 | ) |
| 240 | |
| 241 | # check if the file exists |
| 242 | # TODO: race condition if file is deleted/reated |
| 243 | file_exists = ql.os.fs_mapper.file_exists(s_lpFileName) |
| 244 | |
| 245 | if (open_existing and (not file_exists)): |
| 246 | # the CreationDisposition wants a file to exist |
| 247 | # it does not |
| 248 | ql.os.last_error = ERROR_FILE_NOT_FOUND |
| 249 | return INVALID_HANDLE_VALUE |
| 250 | |
| 251 | if ((dwCreationDisposition == CREATE_NEW ) and file_exists): |
| 252 | # only create a file if it does not exist. |
| 253 | # if it does, error |
| 254 | ql.os.last_error = ERROR_FILE_EXISTS |
| 255 | |
| 256 | truncate = (dwCreationDisposition == CREATE_ALWAYS) or (dwCreationDisposition == TRUNCATE_EXISTING) |
| 257 | |
| 258 | # TODO: this function does not handle general access masks. |
| 259 | # see https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask |
| 260 | # it is only able to handle Generic R/W |
| 261 | |
| 262 | # read only |
| 263 | if (perm_read) and ( not (perm_write)): |
| 264 | mode = "rb" |
| 265 | |
| 266 | # Write only |
| 267 | elif ( perm_write and (not perm_read)): |
| 268 | # TODO: fopen modes do not allow for write only access |
| 269 | # Likely need to use os.open instead. |
| 270 | |
| 271 | if (truncate and (not open_existing)) or (truncate and open_existing and file_exists): |