OK, so [] does dereference the pointer as I guessed. Dereferencing isn't going to solve the problem. _b1 is defined as "_b1 db 'LINK',0", i.e. _b1 is the address of the L which is the first character of a null-terminated string. If you invoke the program as you want, i.e. "program LINK FILE" then LINK will be in argv[1] and FILE in argv[2] (*), so just set _b1 and _b2 equal to argv[1] and argv[2] (which also contain the address of the first character of a null-terminated string).
Code:
mov _b1, (whatever is equivalent to argv[1])
mov _b2, (whatever is equivalent to argv[2])
invoke URLDownloadToFileA,0,_b1,_b2,0,0
(*) Assuming that, say, program "C:\a b c\link" "C:\d e f\file" results in argv containing two items and not 6 (which would be "C:\a, b, c\link", "C:\d, e, f\file" (comma separated)) (yeah I know the first is a URL but this is illustrative only). If you get 6 items then obviously you're going to have to do some string manipulation before you can assign _b1 and _b2.